* [PATCH 0/8] qom: pass TargetInfo to the is_available callback
@ 2026-10-07 11:47 Yonggang Luo
2026-10-07 11:47 ` [PATCH 1/8] configs/targets: remove target info definitions Yonggang Luo
` (9 more replies)
0 siblings, 10 replies; 62+ messages in thread
From: Yonggang Luo @ 2026-10-07 11:47 UTC (permalink / raw)
To: qemu-devel
Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi,
Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow,
Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas,
Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne,
Pierrick Bouvier, qemu-arm, Philippe Mathieu-Daude, Peter Maydell,
Paolo Bonzini, Philippe Mathieu-Daudé,
Marc-André Lureau, Steven Lee, Alexander Bulekov,
Darren Kenny
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
```
It moves target_info() to a shared location so object.c can call it when
checking machine availability. The series also replaces QOM-based target-info
registration with a constructor list and passes TargetInfo to the
is_available callback.
Target metadata and architecture checks are generated from the configured
targets, there is too much arch to write biiolperate code. doing this for easier
Add TargetInfo* to is_available
The target-info API and implementation are shared, rather than compiled
separately for every target.
This series removes the per-target source files "configs/targets/*.c".
Their target-specific parameters are collected in a generated
target-info-def.c for each softmmu target. This lays the groundwork for
QEMU system builds in which target-info-def.c is the only target-specific
source file compiled for each target. Using the same filename lets
meson.build handle these definitions uniformly.
The series adds unit-test coverage for target info and multi-target builds.
Pierrick Bouvier (2):
configs/targets: remove target info definitions
target-info: rename target-info-stub.c in target-info-def.c
Yonggang Luo (6):
target-info: rename target-info-impl.h to target-info-def.h
target-info: replace QOM registration with a constructor list
tests/unit: add target-info coverage for multi-target builds
meson: load all target .mak files into target_mak_all
target-info: Replace handwritten architecture checks with generated
code
qom: pass TargetInfo to is_available for later use
MAINTAINERS | 2 +-
configs/targets/aarch64-softmmu.c | 25 ------
configs/targets/arm-softmmu.c | 25 ------
configs/targets/meson.build | 6 --
configs/targets/riscv32-softmmu.c | 24 -----
configs/targets/riscv64-softmmu.c | 24 -----
hw/arm/aspeed_ast27x0-fc.c | 2 +-
hw/arm/aspeed_ast27x0_evb.c | 4 +-
hw/arm/raspi.c | 4 +-
hw/arm/raspi4b.c | 2 +-
hw/arm/virt.c | 4 +-
hw/m68k/virt.c | 4 +-
hw/or1k/virt.c | 2 +-
include/hw/core/cpu.h | 2 +-
include/qemu/module.h | 1 -
include/qemu/target-info-def.h | 88 ++++++++++++++++++
include/qemu/target-info-impl.h | 42 ---------
include/qemu/target-info-init.h | 53 -----------
include/qemu/target-info-qom.h | 31 -------
include/qemu/target-info.h | 87 ++++--------------
include/qom/object.h | 12 ++-
meson.build | 52 ++++++++---
page-vary-common.c | 2 +-
page-vary-system.c | 2 +-
qom/object.c | 3 +-
scripts/gen-target-info.py | 99 ++++++++++++++++++++
system/vl.c | 4 -
target-info-stub.c => target-info-def.c | 3 +-
target-info-qom.c | 60 -------------
target-info.c | 115 ++++++++++++------------
tests/qtest/fuzz/fuzz.c | 3 -
tests/unit/meson.build | 4 +
tests/unit/test-multi-target.c | 12 +--
tests/unit/test-target-info.c | 38 ++++++++
34 files changed, 379 insertions(+), 462 deletions(-)
delete mode 100644 configs/targets/aarch64-softmmu.c
delete mode 100644 configs/targets/arm-softmmu.c
delete mode 100644 configs/targets/meson.build
delete mode 100644 configs/targets/riscv32-softmmu.c
delete mode 100644 configs/targets/riscv64-softmmu.c
create mode 100644 include/qemu/target-info-def.h
delete mode 100644 include/qemu/target-info-impl.h
delete mode 100644 include/qemu/target-info-init.h
delete mode 100644 include/qemu/target-info-qom.h
create mode 100644 scripts/gen-target-info.py
rename target-info-stub.c => target-info-def.c (94%)
delete mode 100644 target-info-qom.c
create mode 100644 tests/unit/test-target-info.c
--
2.55.0.windows.3
^ permalink raw reply [flat|nested] 62+ messages in thread* [PATCH 1/8] configs/targets: remove target info definitions 2026-10-07 11:47 [PATCH 0/8] qom: pass TargetInfo to the is_available callback Yonggang Luo @ 2026-10-07 11:47 ` Yonggang Luo 2026-10-07 20:26 ` Pierrick Bouvier 2026-10-07 11:47 ` [PATCH 2/8] target-info: rename target-info-stub.c in target-info-def.c Yonggang Luo ` (8 subsequent siblings) 9 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-07 11:47 UTC (permalink / raw) To: qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, Pierrick Bouvier, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Now that we remove machine_typename, we don't need to keep duplicated file per target anymore. So we can just rely on target-info-stub.c. Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> --- MAINTAINERS | 1 - configs/targets/aarch64-softmmu.c | 25 ------------------------- configs/targets/arm-softmmu.c | 25 ------------------------- configs/targets/meson.build | 6 ------ configs/targets/riscv32-softmmu.c | 24 ------------------------ configs/targets/riscv64-softmmu.c | 24 ------------------------ meson.build | 7 +------ 7 files changed, 1 insertion(+), 111 deletions(-) delete mode 100644 configs/targets/aarch64-softmmu.c delete mode 100644 configs/targets/arm-softmmu.c delete mode 100644 configs/targets/meson.build delete mode 100644 configs/targets/riscv32-softmmu.c delete mode 100644 configs/targets/riscv64-softmmu.c diff --git a/MAINTAINERS b/MAINTAINERS index 1312bbd1bd8..cfe39dc2883 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2148,7 +2148,6 @@ M: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> S: Supported F: include/qemu/target-info*.h F: target-info*.c -F: configs/targets/*.c F: tests/unit/test-multi-targets.c Xtensa Machines diff --git a/configs/targets/aarch64-softmmu.c b/configs/targets/aarch64-softmmu.c deleted file mode 100644 index fdebdcc3582..00000000000 --- a/configs/targets/aarch64-softmmu.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * QEMU binary/target API (qemu-system-aarch64) - * - * Copyright (c) Linaro - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "qemu/osdep.h" -#include "qemu/target-info-impl.h" -#include "qemu/target-info-init.h" -#include "target/arm/cpu-qom.h" -#include "target/arm/cpu-param.h" - -static const TargetInfo target_info_aarch64_system = { - .target_name = "aarch64", - .target_arch = SYS_EMU_TARGET_AARCH64, - .long_bits = 64, - .cpu_type = TYPE_ARM_CPU, - .endianness = ENDIAN_MODE_LITTLE, - .page_bits_vary = true, - .page_bits_init = TARGET_PAGE_BITS_LEGACY, -}; - -target_info_init(target_info_aarch64_system) diff --git a/configs/targets/arm-softmmu.c b/configs/targets/arm-softmmu.c deleted file mode 100644 index 2b98f65a0f8..00000000000 --- a/configs/targets/arm-softmmu.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * QEMU binary/target API (qemu-system-arm) - * - * Copyright (c) Linaro - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "qemu/osdep.h" -#include "qemu/target-info-impl.h" -#include "qemu/target-info-init.h" -#include "target/arm/cpu-qom.h" -#include "target/arm/cpu-param.h" - -static const TargetInfo target_info_arm_system = { - .target_name = "arm", - .target_arch = SYS_EMU_TARGET_ARM, - .long_bits = 32, - .cpu_type = TYPE_ARM_CPU, - .endianness = ENDIAN_MODE_LITTLE, - .page_bits_vary = true, - .page_bits_init = TARGET_PAGE_BITS_LEGACY, -}; - -target_info_init(target_info_arm_system) diff --git a/configs/targets/meson.build b/configs/targets/meson.build deleted file mode 100644 index 2ab4d27eaf5..00000000000 --- a/configs/targets/meson.build +++ /dev/null @@ -1,6 +0,0 @@ -foreach target : [ - 'arm-softmmu', 'aarch64-softmmu', - 'riscv32-softmmu', 'riscv64-softmmu' - ] - config_target_info += {target : files(target + '.c')} -endforeach diff --git a/configs/targets/riscv32-softmmu.c b/configs/targets/riscv32-softmmu.c deleted file mode 100644 index 0829ab84de5..00000000000 --- a/configs/targets/riscv32-softmmu.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * QEMU binary/target API (qemu-system-riscv32) - * - * Copyright (c) rev.ng Labs Srl. - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "qemu/osdep.h" -#include "qemu/target-info-impl.h" -#include "qemu/target-info-init.h" -#include "target/riscv/cpu-qom.h" -#include "target/riscv/cpu-param.h" - -static const TargetInfo target_info_riscv32_system = { - .target_name = "riscv32", - .target_arch = SYS_EMU_TARGET_RISCV32, - .long_bits = 32, - .cpu_type = TYPE_RISCV_CPU, - .endianness = ENDIAN_MODE_LITTLE, - .page_bits_init = TARGET_PAGE_BITS, -}; - -target_info_init(target_info_riscv32_system) diff --git a/configs/targets/riscv64-softmmu.c b/configs/targets/riscv64-softmmu.c deleted file mode 100644 index 553bd1f75fe..00000000000 --- a/configs/targets/riscv64-softmmu.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * QEMU binary/target API (qemu-system-riscv64) - * - * Copyright (c) rev.ng Labs Srl. - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "qemu/osdep.h" -#include "qemu/target-info-impl.h" -#include "qemu/target-info-init.h" -#include "target/riscv/cpu-qom.h" -#include "target/riscv/cpu-param.h" - -static const TargetInfo target_info_riscv64_system = { - .target_name = "riscv64", - .target_arch = SYS_EMU_TARGET_RISCV64, - .long_bits = 64, - .cpu_type = TYPE_RISCV_CPU, - .endianness = ENDIAN_MODE_LITTLE, - .page_bits_init = TARGET_PAGE_BITS, -}; - -target_info_init(target_info_riscv64_system) diff --git a/meson.build b/meson.build index 828100de816..64d3f7675f7 100644 --- a/meson.build +++ b/meson.build @@ -3754,7 +3754,6 @@ subdir('dump') subdir('accel') subdir('backends') -subdir('configs/targets') subdir('disas') subdir('migration') subdir('monitor') @@ -4346,11 +4345,7 @@ foreach target : target_dirs endif endif - if target in config_target_info - arch_srcs += config_target_info[target] - else - arch_srcs += files('target-info-stub.c') - endif + arch_srcs += files('target-info-stub.c') if target_base_arch in target_arch t = target_arch[target_base_arch].apply(config_target, strict: false) -- 2.55.0.windows.3 ^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [PATCH 1/8] configs/targets: remove target info definitions 2026-10-07 11:47 ` [PATCH 1/8] configs/targets: remove target info definitions Yonggang Luo @ 2026-10-07 20:26 ` Pierrick Bouvier 2026-10-08 9:46 ` Philippe Mathieu-Daudé 0 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-07 20:26 UTC (permalink / raw) To: Yonggang Luo, qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/7/2026 4:47 AM, Yonggang Luo wrote: > From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> > > Now that we remove machine_typename, we don't need to keep duplicated > file per target anymore. So we can just rely on target-info-stub.c. > > Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > --- > MAINTAINERS | 1 - > configs/targets/aarch64-softmmu.c | 25 ------------------------- > configs/targets/arm-softmmu.c | 25 ------------------------- > configs/targets/meson.build | 6 ------ > configs/targets/riscv32-softmmu.c | 24 ------------------------ > configs/targets/riscv64-softmmu.c | 24 ------------------------ > meson.build | 7 +------ > 7 files changed, 1 insertion(+), 111 deletions(-) > delete mode 100644 configs/targets/aarch64-softmmu.c > delete mode 100644 configs/targets/arm-softmmu.c > delete mode 100644 configs/targets/meson.build > delete mode 100644 configs/targets/riscv32-softmmu.c > delete mode 100644 configs/targets/riscv64-softmmu.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index 1312bbd1bd8..cfe39dc2883 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -2148,7 +2148,6 @@ M: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> > S: Supported > F: include/qemu/target-info*.h > F: target-info*.c > -F: configs/targets/*.c > F: tests/unit/test-multi-targets.c > > Xtensa Machines > diff --git a/configs/targets/aarch64-softmmu.c b/configs/targets/aarch64-softmmu.c > deleted file mode 100644 > index fdebdcc3582..00000000000 > --- a/configs/targets/aarch64-softmmu.c > +++ /dev/null > @@ -1,25 +0,0 @@ > -/* > - * QEMU binary/target API (qemu-system-aarch64) > - * > - * Copyright (c) Linaro > - * > - * SPDX-License-Identifier: GPL-2.0-or-later > - */ > - > -#include "qemu/osdep.h" > -#include "qemu/target-info-impl.h" > -#include "qemu/target-info-init.h" > -#include "target/arm/cpu-qom.h" > -#include "target/arm/cpu-param.h" > - > -static const TargetInfo target_info_aarch64_system = { > - .target_name = "aarch64", > - .target_arch = SYS_EMU_TARGET_AARCH64, > - .long_bits = 64, > - .cpu_type = TYPE_ARM_CPU, > - .endianness = ENDIAN_MODE_LITTLE, > - .page_bits_vary = true, > - .page_bits_init = TARGET_PAGE_BITS_LEGACY, > -}; > - > -target_info_init(target_info_aarch64_system) > diff --git a/configs/targets/arm-softmmu.c b/configs/targets/arm-softmmu.c > deleted file mode 100644 > index 2b98f65a0f8..00000000000 > --- a/configs/targets/arm-softmmu.c > +++ /dev/null > @@ -1,25 +0,0 @@ > -/* > - * QEMU binary/target API (qemu-system-arm) > - * > - * Copyright (c) Linaro > - * > - * SPDX-License-Identifier: GPL-2.0-or-later > - */ > - > -#include "qemu/osdep.h" > -#include "qemu/target-info-impl.h" > -#include "qemu/target-info-init.h" > -#include "target/arm/cpu-qom.h" > -#include "target/arm/cpu-param.h" > - > -static const TargetInfo target_info_arm_system = { > - .target_name = "arm", > - .target_arch = SYS_EMU_TARGET_ARM, > - .long_bits = 32, > - .cpu_type = TYPE_ARM_CPU, > - .endianness = ENDIAN_MODE_LITTLE, > - .page_bits_vary = true, > - .page_bits_init = TARGET_PAGE_BITS_LEGACY, > -}; > - > -target_info_init(target_info_arm_system) > diff --git a/configs/targets/meson.build b/configs/targets/meson.build > deleted file mode 100644 > index 2ab4d27eaf5..00000000000 > --- a/configs/targets/meson.build > +++ /dev/null > @@ -1,6 +0,0 @@ > -foreach target : [ > - 'arm-softmmu', 'aarch64-softmmu', > - 'riscv32-softmmu', 'riscv64-softmmu' > - ] > - config_target_info += {target : files(target + '.c')} > -endforeach > diff --git a/configs/targets/riscv32-softmmu.c b/configs/targets/riscv32-softmmu.c > deleted file mode 100644 > index 0829ab84de5..00000000000 > --- a/configs/targets/riscv32-softmmu.c > +++ /dev/null > @@ -1,24 +0,0 @@ > -/* > - * QEMU binary/target API (qemu-system-riscv32) > - * > - * Copyright (c) rev.ng Labs Srl. > - * > - * SPDX-License-Identifier: GPL-2.0-or-later > - */ > - > -#include "qemu/osdep.h" > -#include "qemu/target-info-impl.h" > -#include "qemu/target-info-init.h" > -#include "target/riscv/cpu-qom.h" > -#include "target/riscv/cpu-param.h" > - > -static const TargetInfo target_info_riscv32_system = { > - .target_name = "riscv32", > - .target_arch = SYS_EMU_TARGET_RISCV32, > - .long_bits = 32, > - .cpu_type = TYPE_RISCV_CPU, > - .endianness = ENDIAN_MODE_LITTLE, > - .page_bits_init = TARGET_PAGE_BITS, > -}; > - > -target_info_init(target_info_riscv32_system) > diff --git a/configs/targets/riscv64-softmmu.c b/configs/targets/riscv64-softmmu.c > deleted file mode 100644 > index 553bd1f75fe..00000000000 > --- a/configs/targets/riscv64-softmmu.c > +++ /dev/null > @@ -1,24 +0,0 @@ > -/* > - * QEMU binary/target API (qemu-system-riscv64) > - * > - * Copyright (c) rev.ng Labs Srl. > - * > - * SPDX-License-Identifier: GPL-2.0-or-later > - */ > - > -#include "qemu/osdep.h" > -#include "qemu/target-info-impl.h" > -#include "qemu/target-info-init.h" > -#include "target/riscv/cpu-qom.h" > -#include "target/riscv/cpu-param.h" > - > -static const TargetInfo target_info_riscv64_system = { > - .target_name = "riscv64", > - .target_arch = SYS_EMU_TARGET_RISCV64, > - .long_bits = 64, > - .cpu_type = TYPE_RISCV_CPU, > - .endianness = ENDIAN_MODE_LITTLE, > - .page_bits_init = TARGET_PAGE_BITS, > -}; > - > -target_info_init(target_info_riscv64_system) > diff --git a/meson.build b/meson.build > index 828100de816..64d3f7675f7 100644 > --- a/meson.build > +++ b/meson.build > @@ -3754,7 +3754,6 @@ subdir('dump') > subdir('accel') > > subdir('backends') > -subdir('configs/targets') > subdir('disas') > subdir('migration') > subdir('monitor') > @@ -4346,11 +4345,7 @@ foreach target : target_dirs > endif > endif > > - if target in config_target_info > - arch_srcs += config_target_info[target] > - else > - arch_srcs += files('target-info-stub.c') > - endif > + arch_srcs += files('target-info-stub.c') > > if target_base_arch in target_arch > t = target_arch[target_base_arch].apply(config_target, strict: false) We delayed this patch because initially we thought we might need to add other things in this struct (per target). However, it was not proven it was needed, thus I'll pull this. Thanks, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 1/8] configs/targets: remove target info definitions 2026-10-07 20:26 ` Pierrick Bouvier @ 2026-10-08 9:46 ` Philippe Mathieu-Daudé 0 siblings, 0 replies; 62+ messages in thread From: Philippe Mathieu-Daudé @ 2026-10-08 9:46 UTC (permalink / raw) To: Pierrick Bouvier, Yonggang Luo, qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 7/10/26 22:26, Pierrick Bouvier wrote: > On 10/7/2026 4:47 AM, Yonggang Luo wrote: >> From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> >> >> Now that we remove machine_typename, we don't need to keep duplicated >> file per target anymore. So we can just rely on target-info-stub.c. >> >> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> >> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> >> --- >> MAINTAINERS | 1 - >> configs/targets/aarch64-softmmu.c | 25 ------------------------- >> configs/targets/arm-softmmu.c | 25 ------------------------- >> configs/targets/meson.build | 6 ------ >> configs/targets/riscv32-softmmu.c | 24 ------------------------ >> configs/targets/riscv64-softmmu.c | 24 ------------------------ >> meson.build | 7 +------ >> 7 files changed, 1 insertion(+), 111 deletions(-) >> delete mode 100644 configs/targets/aarch64-softmmu.c >> delete mode 100644 configs/targets/arm-softmmu.c >> delete mode 100644 configs/targets/meson.build >> delete mode 100644 configs/targets/riscv32-softmmu.c >> delete mode 100644 configs/targets/riscv64-softmmu.c >> diff --git a/configs/targets/riscv64-softmmu.c b/configs/targets/riscv64-softmmu.c >> deleted file mode 100644 >> index 553bd1f75fe..00000000000 >> --- a/configs/targets/riscv64-softmmu.c >> +++ /dev/null >> @@ -1,24 +0,0 @@ >> -/* >> - * QEMU binary/target API (qemu-system-riscv64) >> - * >> - * Copyright (c) rev.ng Labs Srl. >> - * >> - * SPDX-License-Identifier: GPL-2.0-or-later >> - */ >> - >> -#include "qemu/osdep.h" >> -#include "qemu/target-info-impl.h" >> -#include "qemu/target-info-init.h" >> -#include "target/riscv/cpu-qom.h" >> -#include "target/riscv/cpu-param.h" >> - >> -static const TargetInfo target_info_riscv64_system = { >> - .target_name = "riscv64", >> - .target_arch = SYS_EMU_TARGET_RISCV64, >> - .long_bits = 64, >> - .cpu_type = TYPE_RISCV_CPU, >> - .endianness = ENDIAN_MODE_LITTLE, >> - .page_bits_init = TARGET_PAGE_BITS, >> -}; >> - >> -target_info_init(target_info_riscv64_system) >> diff --git a/meson.build b/meson.build >> index 828100de816..64d3f7675f7 100644 >> --- a/meson.build >> +++ b/meson.build >> @@ -3754,7 +3754,6 @@ subdir('dump') >> subdir('accel') >> >> subdir('backends') >> -subdir('configs/targets') >> subdir('disas') >> subdir('migration') >> subdir('monitor') >> @@ -4346,11 +4345,7 @@ foreach target : target_dirs >> endif >> endif >> >> - if target in config_target_info >> - arch_srcs += config_target_info[target] >> - else >> - arch_srcs += files('target-info-stub.c') >> - endif >> + arch_srcs += files('target-info-stub.c') >> >> if target_base_arch in target_arch >> t = target_arch[target_base_arch].apply(config_target, strict: false) > > We delayed this patch because initially we thought we might need to add > other things in this struct (per target). However, it was not proven it > was needed, thus I'll pull this. I think because in early prototype I was initializing manually with a 2-target {&target_info_aarch64, &target_info_microblaze} explicit set, but this predates target_info_init() which does the QOM type registration, so today we can simply use a set of QOM typenames IIUC. ^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 2/8] target-info: rename target-info-stub.c in target-info-def.c 2026-10-07 11:47 [PATCH 0/8] qom: pass TargetInfo to the is_available callback Yonggang Luo 2026-10-07 11:47 ` [PATCH 1/8] configs/targets: remove target info definitions Yonggang Luo @ 2026-10-07 11:47 ` Yonggang Luo 2026-10-07 11:48 ` [PATCH 3/8] target-info: rename target-info-impl.h to target-info-def.h Yonggang Luo ` (7 subsequent siblings) 9 siblings, 0 replies; 62+ messages in thread From: Yonggang Luo @ 2026-10-07 11:47 UTC (permalink / raw) To: qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, Pierrick Bouvier, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Now it's the only file left to define target info, we call it def to make the intent more clear. Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> --- include/hw/core/cpu.h | 2 +- meson.build | 2 +- target-info-stub.c => target-info-def.c | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename target-info-stub.c => target-info-def.c (100%) diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 328e30045ce..ae66f5e33e3 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -601,7 +601,7 @@ QEMU_BUILD_BUG_ON(offsetof(CPUState, neg) != * Return the CPUArchState associated with the CPU. */ #define cpu_env(cpu) _Generic(cpu, \ - /* We validate that CPUArchState follows CPUState in target-info-stub.c */ \ + /* We validate that CPUArchState follows CPUState in target-info-def.c */ \ CPUState *: \ (CPUArchState *)((cpu) + 1), \ const CPUState *: \ diff --git a/meson.build b/meson.build index 64d3f7675f7..ac78c58cb91 100644 --- a/meson.build +++ b/meson.build @@ -4345,7 +4345,7 @@ foreach target : target_dirs endif endif - arch_srcs += files('target-info-stub.c') + arch_srcs += files('target-info-def.c') if target_base_arch in target_arch t = target_arch[target_base_arch].apply(config_target, strict: false) diff --git a/target-info-stub.c b/target-info-def.c similarity index 100% rename from target-info-stub.c rename to target-info-def.c -- 2.55.0.windows.3 ^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 3/8] target-info: rename target-info-impl.h to target-info-def.h 2026-10-07 11:47 [PATCH 0/8] qom: pass TargetInfo to the is_available callback Yonggang Luo 2026-10-07 11:47 ` [PATCH 1/8] configs/targets: remove target info definitions Yonggang Luo 2026-10-07 11:47 ` [PATCH 2/8] target-info: rename target-info-stub.c in target-info-def.c Yonggang Luo @ 2026-10-07 11:48 ` Yonggang Luo 2026-10-07 20:27 ` Pierrick Bouvier 2026-10-07 11:48 ` [PATCH 4/8] target-info: replace QOM registration with a constructor list Yonggang Luo ` (6 subsequent siblings) 9 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-07 11:48 UTC (permalink / raw) To: qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, Pierrick Bouvier, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny Rename the TargetInfo structure header and its include guard. Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> --- include/qemu/{target-info-impl.h => target-info-def.h} | 4 ++-- include/qemu/target-info-qom.h | 2 +- page-vary-common.c | 2 +- page-vary-system.c | 2 +- target-info-def.c | 2 +- target-info-qom.c | 2 +- target-info.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) rename include/qemu/{target-info-impl.h => target-info-def.h} (94%) diff --git a/include/qemu/target-info-impl.h b/include/qemu/target-info-def.h similarity index 94% rename from include/qemu/target-info-impl.h rename to include/qemu/target-info-def.h index cf42aabbc8b..8019d2c7196 100644 --- a/include/qemu/target-info-impl.h +++ b/include/qemu/target-info-def.h @@ -6,8 +6,8 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ -#ifndef QEMU_TARGET_INFO_IMPL_H -#define QEMU_TARGET_INFO_IMPL_H +#ifndef QEMU_TARGET_INFO_DEF_H +#define QEMU_TARGET_INFO_DEF_H #include "qapi/qapi-types-common.h" #include "qapi/qapi-types-machine.h" diff --git a/include/qemu/target-info-qom.h b/include/qemu/target-info-qom.h index 8b6e1ece969..ba2e4370afb 100644 --- a/include/qemu/target-info-qom.h +++ b/include/qemu/target-info-qom.h @@ -9,7 +9,7 @@ #ifndef QEMU_TARGET_INFO_QOM_H #define QEMU_TARGET_INFO_QOM_H -#include "qemu/target-info-impl.h" +#include "qemu/target-info-def.h" #include "qom/object.h" #define TYPE_TARGET_INFO "target-info" diff --git a/page-vary-common.c b/page-vary-common.c index ddd08633788..5a4654725a8 100644 --- a/page-vary-common.c +++ b/page-vary-common.c @@ -20,7 +20,7 @@ #define IN_PAGE_VARY 1 #include "qemu/osdep.h" -#include "qemu/target-info-impl.h" +#include "qemu/target-info-def.h" #include "exec/page-vary.h" /* WARNING: This file must *not* be complied with -flto. */ diff --git a/page-vary-system.c b/page-vary-system.c index 6c49c10e23b..9773685dc16 100644 --- a/page-vary-system.c +++ b/page-vary-system.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "exec/page-vary.h" #include "exec/tlb-flags.h" -#include "qemu/target-info-impl.h" +#include "qemu/target-info-def.h" QEMU_BUILD_BUG_ON(TLB_FLAGS_MASK & ((1u < TARGET_PAGE_BITS_MIN) - 1)); diff --git a/target-info-def.c b/target-info-def.c index d121b8c0170..fa19cabc55f 100644 --- a/target-info-def.c +++ b/target-info-def.c @@ -8,7 +8,7 @@ #include "qemu/osdep.h" #include "qemu/target-info.h" -#include "qemu/target-info-impl.h" +#include "qemu/target-info-def.h" #include "qemu/target-info-init.h" #include "hw/core/boards.h" #include "cpu.h" diff --git a/target-info-qom.c b/target-info-qom.c index 3ae1627b8fb..aeeedb7e818 100644 --- a/target-info-qom.c +++ b/target-info-qom.c @@ -9,7 +9,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qom/object.h" -#include "qemu/target-info-impl.h" +#include "qemu/target-info-def.h" #include "qemu/target-info-init.h" #include "qemu/target-info-qom.h" diff --git a/target-info.c b/target-info.c index ab43c9f802c..6b365113955 100644 --- a/target-info.c +++ b/target-info.c @@ -9,7 +9,7 @@ #include "qemu/osdep.h" #include "qemu/target-info.h" #include "qemu/target-info-qapi.h" -#include "qemu/target-info-impl.h" +#include "qemu/target-info-def.h" #include "qapi/error.h" const char *target_name(void) -- 2.55.0.windows.3 ^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [PATCH 3/8] target-info: rename target-info-impl.h to target-info-def.h 2026-10-07 11:48 ` [PATCH 3/8] target-info: rename target-info-impl.h to target-info-def.h Yonggang Luo @ 2026-10-07 20:27 ` Pierrick Bouvier 0 siblings, 0 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-07 20:27 UTC (permalink / raw) To: Yonggang Luo, qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/7/2026 4:48 AM, Yonggang Luo wrote: > Rename the TargetInfo structure header and its include guard. > > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > --- > include/qemu/{target-info-impl.h => target-info-def.h} | 4 ++-- > include/qemu/target-info-qom.h | 2 +- > page-vary-common.c | 2 +- > page-vary-system.c | 2 +- > target-info-def.c | 2 +- > target-info-qom.c | 2 +- > target-info.c | 2 +- > 7 files changed, 8 insertions(+), 8 deletions(-) > rename include/qemu/{target-info-impl.h => target-info-def.h} (94%) > Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> ^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-07 11:47 [PATCH 0/8] qom: pass TargetInfo to the is_available callback Yonggang Luo ` (2 preceding siblings ...) 2026-10-07 11:48 ` [PATCH 3/8] target-info: rename target-info-impl.h to target-info-def.h Yonggang Luo @ 2026-10-07 11:48 ` Yonggang Luo 2026-10-07 20:29 ` Pierrick Bouvier 2026-10-07 11:48 ` [PATCH 5/8] tests/unit: add target-info coverage for multi-target builds Yonggang Luo ` (5 subsequent siblings) 9 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-07 11:48 UTC (permalink / raw) To: qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, Pierrick Bouvier, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny Register target definitions through constructors instead of MODULE_INIT_TARGET_INFO, making target_info_list() and target_info() available on entry to main(), without explicit initialization or a call to module_call_init(MODULE_INIT_QOM). Keep the target list sorted by target_arch and default to its first entry. Provide an unknown TargetInfo fallback for target-independent tools such as qemu-img and unit tests that link no target-info-def.c objects. Remove the obsolete QOM target-info registration infrastructure and update the multi-target test to inspect target information before initializing QOM. Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> --- include/qemu/module.h | 1 - include/qemu/target-info-def.h | 56 +++++++++++++++++++++++++++--- include/qemu/target-info-init.h | 53 ---------------------------- include/qemu/target-info-qom.h | 31 ----------------- include/qemu/target-info.h | 9 +++++ meson.build | 6 ++-- system/vl.c | 4 --- target-info-def.c | 1 - target-info-qom.c | 60 -------------------------------- target-info.c | 61 ++++++++++++++++++++++++++++++++- tests/qtest/fuzz/fuzz.c | 3 -- tests/unit/test-multi-target.c | 12 +++---- 12 files changed, 129 insertions(+), 168 deletions(-) delete mode 100644 include/qemu/target-info-init.h delete mode 100644 include/qemu/target-info-qom.h delete mode 100644 target-info-qom.c diff --git a/include/qemu/module.h b/include/qemu/module.h index fccf017bf9e..9885ac9afb3 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -43,7 +43,6 @@ typedef enum { MODULE_INIT_MIGRATION, MODULE_INIT_BLOCK, MODULE_INIT_OPTS, - MODULE_INIT_TARGET_INFO, MODULE_INIT_QOM, MODULE_INIT_TRACE, MODULE_INIT_XEN_BACKEND, diff --git a/include/qemu/target-info-def.h b/include/qemu/target-info-def.h index 8019d2c7196..080e30a5b0e 100644 --- a/include/qemu/target-info-def.h +++ b/include/qemu/target-info-def.h @@ -11,8 +11,10 @@ #include "qapi/qapi-types-common.h" #include "qapi/qapi-types-machine.h" +#include "qemu/queue.h" +#include "qemu/target-info.h" -typedef struct TargetInfo { +struct TargetInfo { /* runtime equivalent of TARGET_NAME definition */ const char *target_name; /* related to TARGET_ARCH definition */ @@ -30,13 +32,57 @@ typedef struct TargetInfo { unsigned page_bits_init; /* runtime equivalent of TARGET_PAGE_BITS_VARY definition */ bool page_bits_vary; -} TargetInfo; +}; + +typedef struct TargetInfoNode TargetInfoNode; +typedef QLIST_HEAD(, TargetInfoNode) TargetInfoList; + +struct TargetInfoNode { + const TargetInfo *info; + QLIST_ENTRY(TargetInfoNode) next; +}; + +/** + * target_info_list: + * + * TargetInfo is a static list, not a QOM type. Constructors insert + * entries before main(), so type_init can use it. + * + * Returns: registered TargetInfoNode list head, sorted by + * info->target_arch. The list is owned by target-info + * and must not be modified. Iterate with + * QLIST_FOREACH(..., next) and use node->info. + */ +const TargetInfoList *target_info_list(void); /** - * target_info: + * target_info_select: + * @ti: TargetInfo to make current * - * Returns: The TargetInfo structure definition for this target binary. + * Sets target_info() to @ti. + */ +void target_info_select(const TargetInfo *ti); + +/** + * target_info_list_add: + * @node: static TargetInfoNode whose info points at a const TargetInfo + * + * Inserts @node into target_info_list(), sorted by info->target_arch. + * Sets target_info() to the first list entry. + */ +void target_info_list_add(TargetInfoNode *node); + +/* + * Register @ti before main(). Linked into the executable, not a DSO. + * @ti is a unique identifier in this translation unit. */ -const TargetInfo *target_info(void); +#define target_info_init(ti) \ + static TargetInfoNode ti##_node = { \ + .info = &(ti), \ + }; \ + static void __attribute__((constructor)) do_qemu_init_##ti(void) \ + { \ + target_info_list_add(&ti##_node); \ + } #endif diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h deleted file mode 100644 index b7024c9faef..00000000000 --- a/include/qemu/target-info-init.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * QEMU target info initialization - * - * Copyright (c) Qualcomm - * - * SPDX-License-Identifier: GPL-2.0-or-later - * - * This file is included by each file defining a TargetInfo structure and is - * responsible for registering it. - */ - -#ifndef QEMU_TARGET_INFO_INIT_H -#define QEMU_TARGET_INFO_INIT_H - -#define DEFINE_TARGET_INFO_TYPE(info) \ -static void do_qemu_init_target_info(void) \ -{ \ - type_register_static(&info); \ -} \ -module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO) - -#ifdef COMPILING_PER_TARGET -#ifdef CONFIG_USER_ONLY - -/* - * User mode does not support multiple targets in the same binary, so just - * define target_info(). - */ -#define target_info_init(ti_var) \ -const TargetInfo *target_info(void) \ -{ \ - return &ti_var; \ -} - -#else /* CONFIG_USER_ONLY */ - -#include "qemu/target-info-qom.h" -#include "qom/object.h" - -#define target_info_init(ti_var) \ -static const TypeInfo target_info_qom_target_type_info = { \ - .name = TYPE_TARGET_INFO"-"TARGET_NAME, \ - .parent = TYPE_TARGET_INFO, \ - .instance_size = sizeof(TargetInfoQom), \ - .class_size = sizeof(TargetInfoQomClass), \ - .class_data = &ti_var, \ -}; \ -DEFINE_TARGET_INFO_TYPE(target_info_qom_target_type_info) - -#endif /* CONFIG_USER_ONLY */ -#endif /* COMPILING_PER_TARGET */ - -#endif /* QEMU_TARGET_INFO_INIT_H */ diff --git a/include/qemu/target-info-qom.h b/include/qemu/target-info-qom.h deleted file mode 100644 index ba2e4370afb..00000000000 --- a/include/qemu/target-info-qom.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * QEMU target info QOM types - * - * Copyright (c) Qualcomm - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#ifndef QEMU_TARGET_INFO_QOM_H -#define QEMU_TARGET_INFO_QOM_H - -#include "qemu/target-info-def.h" -#include "qom/object.h" - -#define TYPE_TARGET_INFO "target-info" - -typedef struct TargetInfoQom { - Object parent_obj; -} TargetInfoQom; - -typedef struct TargetInfoQomClass { - ObjectClass parent_class; - const TargetInfo *target_info; -} TargetInfoQomClass; - -OBJECT_DECLARE_TYPE(TargetInfoQom, TargetInfoQomClass, TARGET_INFO) - -void target_info_qom_set_target(void); -void target_info_qom_set_target_info(const TargetInfo *ti); - -#endif /* QEMU_TARGET_INFO_QOM_H */ diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h index adda363ac39..d1928cecf84 100644 --- a/include/qemu/target-info.h +++ b/include/qemu/target-info.h @@ -9,6 +9,15 @@ #ifndef QEMU_TARGET_INFO_H #define QEMU_TARGET_INFO_H +typedef struct TargetInfo TargetInfo; + +/** + * target_info: + * + * Returns: The TargetInfo structure definition for the selected target. + */ +const TargetInfo *target_info(void); + /** * target_name: * diff --git a/meson.build b/meson.build index ac78c58cb91..4097784e7a2 100644 --- a/meson.build +++ b/meson.build @@ -3777,6 +3777,9 @@ if enable_modules modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO') endif +qom_ss.add(files( + 'target-info.c', +)) qom_ss = qom_ss.apply({}) libqom = static_library('qom', qom_ss.sources() + genh, dependencies: [qom_ss.dependencies()], @@ -3869,9 +3872,6 @@ endif common_ss.add(pagevary) system_ss.add(files('page-vary-system.c')) -common_ss.add(files('target-info.c')) -system_ss.add(files('target-info-qom.c')) - if 'CONFIG_TCG' in config_all_accel subdir('contrib/plugins') endif diff --git a/system/vl.c b/system/vl.c index 468a9fc247a..2c50aa01a2e 100644 --- a/system/vl.c +++ b/system/vl.c @@ -28,7 +28,6 @@ #include "qemu/units.h" #include "qemu/module.h" #include "qemu/target-info.h" -#include "qemu/target-info-qom.h" #include "exec/cpu-common.h" #include "exec/page-vary.h" #include "hw/core/qdev-properties.h" @@ -2914,9 +2913,6 @@ void qemu_init(int argc, char **argv) os_setup_limits(); - module_call_init(MODULE_INIT_TARGET_INFO); - target_info_qom_set_target(); - module_init_info(qemu_modinfo); module_allow_arch(target_name()); diff --git a/target-info-def.c b/target-info-def.c index fa19cabc55f..3041d64ccd2 100644 --- a/target-info-def.c +++ b/target-info-def.c @@ -9,7 +9,6 @@ #include "qemu/osdep.h" #include "qemu/target-info.h" #include "qemu/target-info-def.h" -#include "qemu/target-info-init.h" #include "hw/core/boards.h" #include "cpu.h" #include "exec/cpu-defs.h" diff --git a/target-info-qom.c b/target-info-qom.c deleted file mode 100644 index aeeedb7e818..00000000000 --- a/target-info-qom.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * QEMU binary/target API (QOM types) - * - * Copyright (c) Linaro - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "qom/object.h" -#include "qemu/target-info-def.h" -#include "qemu/target-info-init.h" -#include "qemu/target-info-qom.h" - -static void target_info_qom_class_init(ObjectClass *oc, const void * data) -{ - TargetInfoQomClass *klass = TARGET_INFO_CLASS(oc); - klass->target_info = data; -} - -static const TypeInfo target_info_parent_type = { - .name = TYPE_TARGET_INFO, - .parent = TYPE_OBJECT, - .instance_size = sizeof(TargetInfoQom), - .class_size = sizeof(TargetInfoQomClass), - /* use class_base_init so children classes can set class_data accordingly */ - .class_base_init = target_info_qom_class_init, - /* children classes will be concrete, which allows to easily query them - * without listing this parent class also */ - .abstract = true, -}; - -DEFINE_TARGET_INFO_TYPE(target_info_parent_type) - -static const TargetInfo *target_info_ptr; - -const TargetInfo *target_info(void) -{ - return target_info_ptr; -} - -void target_info_qom_set_target(void) -{ - g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false); - - size_t num_found = g_slist_length(targets); - if (num_found != 1) { - error_setg(&error_fatal, num_found == 0 ? - "no target-info is available" : - "more than one target-info is available"); - } - - target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info; -} - -void target_info_qom_set_target_info(const TargetInfo *ti) -{ - target_info_ptr = ti; -} diff --git a/target-info.c b/target-info.c index 6b365113955..8ccb333e365 100644 --- a/target-info.c +++ b/target-info.c @@ -10,7 +10,66 @@ #include "qemu/target-info.h" #include "qemu/target-info-qapi.h" #include "qemu/target-info-def.h" -#include "qapi/error.h" +#include "exec/page-vary.h" + +/* + * Tools such as qemu-img and unit tests may link target-info.c without any + * target-info-def.c objects. Their target list remains empty, so use this + * fallback. + */ +static const TargetInfo target_info_default = { + .target_arch = SYS_EMU_TARGET__MAX, + .target_name = "unknown", + .long_bits = 64, + .endianness = ENDIAN_MODE_LITTLE, + .page_bits_init = TARGET_PAGE_BITS_MIN, +}; + +static const TargetInfo *target_info_ptr = &target_info_default; +static TargetInfoList target_infos = QLIST_HEAD_INITIALIZER(target_infos); + +const TargetInfo *target_info(void) +{ + g_assert(target_info_ptr != NULL); + return target_info_ptr; +} + +const TargetInfoList *target_info_list(void) +{ + return &target_infos; +} + +void target_info_select(const TargetInfo *ti) +{ + g_assert(ti != NULL); + target_info_ptr = ti; +} + +void target_info_list_add(TargetInfoNode *node) +{ + const TargetInfo *info; + TargetInfoNode *cur, *prev = NULL; + + g_assert(node && node->info); + info = node->info; + QLIST_FOREACH(cur, &target_infos, next) { + if (info->target_arch < cur->info->target_arch) { + QLIST_INSERT_BEFORE(cur, node, next); + break; + } + prev = cur; + } + if (!cur) { + if (prev) { + QLIST_INSERT_AFTER(prev, node, next); + } else { + QLIST_INSERT_HEAD(&target_infos, node, next); + } + } + + /* Default to the first entry in the target_arch-sorted list. */ + target_info_select(QLIST_FIRST(&target_infos)->info); +} const char *target_name(void) { diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c index a3a131c80f8..d2355989616 100644 --- a/tests/qtest/fuzz/fuzz.c +++ b/tests/qtest/fuzz/fuzz.c @@ -22,7 +22,6 @@ #include "system/runstate.h" #include "qemu/main-loop.h" #include "qemu/rcu.h" -#include "qemu/target-info-qom.h" #include "tests/qtest/libqtest.h" #include "tests/qtest/libqos/qgraph.h" #include "fuzz.h" @@ -173,8 +172,6 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp) /* Initialize qgraph and modules */ qos_graph_init(); - module_call_init(MODULE_INIT_TARGET_INFO); - target_info_qom_set_target(); module_call_init(MODULE_INIT_FUZZ_TARGET); module_call_init(MODULE_INIT_QOM); module_call_init(MODULE_INIT_LIBQOS); diff --git a/tests/unit/test-multi-target.c b/tests/unit/test-multi-target.c index 89b55bb1632..150254a3ba3 100644 --- a/tests/unit/test-multi-target.c +++ b/tests/unit/test-multi-target.c @@ -15,7 +15,7 @@ #include "qemu/osdep.h" #include "qemu/module.h" #include "qemu/target-info.h" -#include "qemu/target-info-qom.h" +#include "qemu/target-info-def.h" #include "qom/object.h" #ifdef CONFIG_SDL @@ -32,11 +32,11 @@ int (*qemu_main)(void); static void test_qom_types_are_unique(void) { - module_call_init(MODULE_INIT_TARGET_INFO); - g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false); - g_assert(targets); - const TargetInfo *first_ti = TARGET_INFO_CLASS(targets->data)->target_info; - target_info_qom_set_target_info(first_ti); + const TargetInfoList *targets = target_info_list(); + + g_assert_nonnull(QLIST_FIRST(targets)); + + g_assert_nonnull(target_info()); /* register all types */ module_call_init(MODULE_INIT_QOM); -- 2.55.0.windows.3 ^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-07 11:48 ` [PATCH 4/8] target-info: replace QOM registration with a constructor list Yonggang Luo @ 2026-10-07 20:29 ` Pierrick Bouvier 2026-10-07 20:50 ` Yonggang Luo 0 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-07 20:29 UTC (permalink / raw) To: Yonggang Luo, qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/7/2026 4:48 AM, Yonggang Luo wrote: > Register target definitions through constructors instead of > MODULE_INIT_TARGET_INFO, making target_info_list() and target_info() > available on entry to main(), without explicit initialization or a > call to module_call_init(MODULE_INIT_QOM). > > Keep the target list sorted by target_arch and default to its first > entry. Provide an unknown TargetInfo fallback for target-independent > tools such as qemu-img and unit tests that link no target-info-def.c > objects. > > Remove the obsolete QOM target-info registration infrastructure and > update the multi-target test to inspect target information before > initializing QOM. > > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > --- > include/qemu/module.h | 1 - > include/qemu/target-info-def.h | 56 +++++++++++++++++++++++++++--- > include/qemu/target-info-init.h | 53 ---------------------------- > include/qemu/target-info-qom.h | 31 ----------------- > include/qemu/target-info.h | 9 +++++ > meson.build | 6 ++-- > system/vl.c | 4 --- > target-info-def.c | 1 - > target-info-qom.c | 60 -------------------------------- > target-info.c | 61 ++++++++++++++++++++++++++++++++- > tests/qtest/fuzz/fuzz.c | 3 -- > tests/unit/test-multi-target.c | 12 +++---- > 12 files changed, 129 insertions(+), 168 deletions(-) > delete mode 100644 include/qemu/target-info-init.h > delete mode 100644 include/qemu/target-info-qom.h > delete mode 100644 target-info-qom.c > This approach (custom list based) was considered before implementing things with QOM Types. The rationale I followed was that if everything is in QOM, we might better follow that for consistency sake. Yes, the compromise if that we need an extra init step, but it was not a problem to add it. Is there another good value this list approach brings compared to what exists? Regards, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-07 20:29 ` Pierrick Bouvier @ 2026-10-07 20:50 ` Yonggang Luo 2026-10-07 22:31 ` Pierrick Bouvier 0 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-07 20:50 UTC (permalink / raw) To: Pierrick Bouvier Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Thu, Oct 8, 2026 at 4:29 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/7/2026 4:48 AM, Yonggang Luo wrote: > > Register target definitions through constructors instead of > > MODULE_INIT_TARGET_INFO, making target_info_list() and target_info() > > available on entry to main(), without explicit initialization or a > > call to module_call_init(MODULE_INIT_QOM). > > > > Keep the target list sorted by target_arch and default to its first > > entry. Provide an unknown TargetInfo fallback for target-independent > > tools such as qemu-img and unit tests that link no target-info-def.c > > objects. > > > > Remove the obsolete QOM target-info registration infrastructure and > > update the multi-target test to inspect target information before > > initializing QOM. > > > > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > > --- > > include/qemu/module.h | 1 - > > include/qemu/target-info-def.h | 56 +++++++++++++++++++++++++++--- > > include/qemu/target-info-init.h | 53 ---------------------------- > > include/qemu/target-info-qom.h | 31 ----------------- > > include/qemu/target-info.h | 9 +++++ > > meson.build | 6 ++-- > > system/vl.c | 4 --- > > target-info-def.c | 1 - > > target-info-qom.c | 60 -------------------------------- > > target-info.c | 61 ++++++++++++++++++++++++++++++++- > > tests/qtest/fuzz/fuzz.c | 3 -- > > tests/unit/test-multi-target.c | 12 +++---- > > 12 files changed, 129 insertions(+), 168 deletions(-) > > delete mode 100644 include/qemu/target-info-init.h > > delete mode 100644 include/qemu/target-info-qom.h > > delete mode 100644 target-info-qom.c > > > > This approach (custom list based) was considered before implementing > things with QOM Types. The rationale I followed was that if everything > is in QOM, we might better follow that for consistency sake. > Yes, the compromise if that we need an extra init step, but it was not a > problem to add it. I have issue to add the init step for unit-tests, and hard to write the -target parse procedure and get it right. Not means this won't work. but for me, too much coupled. If we treat target_info as a QOM, but QOM needs target_info to set up(is_avaible). That makes the init sequence too much of a burden. is_available is depends on target_arch And before this patch, target_arch depends on QOM, pulls user/softmmu because target_info_init. By moving target-info to be a custom list based, we can decouple target-info from qom/softmmu/user. and target-info will always available once "main(argv, argc)" is entered. We also have the advantage of doing all sorts of tests against it. Tools such as qemu-img and unit tests may link target-info.c without any target-info-def.c objects. Their target list remains empty, so use this fallback. static TypeImpl *type_register_internal(const TypeInfo *info) { TypeImpl *ti; if (!type_name_is_valid(info->name)) { fprintf(stderr, "Registering '%s' with illegal type name\n", info->name); abort(); } if (info->is_available && !info->is_available()) { return NULL; } ti = type_new(info); type_table_add(ti); return ti; } > > Is there another good value this list approach brings compared to what > exists? > > Regards, > Pierrick -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-07 20:50 ` Yonggang Luo @ 2026-10-07 22:31 ` Pierrick Bouvier 2026-10-07 22:54 ` Yonggang Luo 2026-10-07 23:02 ` Yonggang Luo 0 siblings, 2 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-07 22:31 UTC (permalink / raw) To: luoyonggang Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/7/2026 1:50 PM, Yonggang Luo wrote: > On Thu, Oct 8, 2026 at 4:29 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> wrote: >> >> On 10/7/2026 4:48 AM, Yonggang Luo wrote: >>> Register target definitions through constructors instead of >>> MODULE_INIT_TARGET_INFO, making target_info_list() and target_info() >>> available on entry to main(), without explicit initialization or a >>> call to module_call_init(MODULE_INIT_QOM). >>> >>> Keep the target list sorted by target_arch and default to its first >>> entry. Provide an unknown TargetInfo fallback for target-independent >>> tools such as qemu-img and unit tests that link no target-info-def.c >>> objects. >>> >>> Remove the obsolete QOM target-info registration infrastructure and >>> update the multi-target test to inspect target information before >>> initializing QOM. >>> >>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> >>> --- >>> include/qemu/module.h | 1 - >>> include/qemu/target-info-def.h | 56 +++++++++++++++++++++++++++--- >>> include/qemu/target-info-init.h | 53 ---------------------------- >>> include/qemu/target-info-qom.h | 31 ----------------- >>> include/qemu/target-info.h | 9 +++++ >>> meson.build | 6 ++-- >>> system/vl.c | 4 --- >>> target-info-def.c | 1 - >>> target-info-qom.c | 60 -------------------------------- >>> target-info.c | 61 ++++++++++++++++++++++++++++++++- >>> tests/qtest/fuzz/fuzz.c | 3 -- >>> tests/unit/test-multi-target.c | 12 +++---- >>> 12 files changed, 129 insertions(+), 168 deletions(-) >>> delete mode 100644 include/qemu/target-info-init.h >>> delete mode 100644 include/qemu/target-info-qom.h >>> delete mode 100644 target-info-qom.c >>> >> >> This approach (custom list based) was considered before implementing >> things with QOM Types. The rationale I followed was that if everything >> is in QOM, we might better follow that for consistency sake. >> Yes, the compromise if that we need an extra init step, but it was not a >> problem to add it. > I have issue to add the init step for unit-tests, and hard to write the -target > parse procedure and get it right. Not means this won't work. but for > me, too much > coupled. > We already have such a test upstream: https://gitlab.com/qemu-project/qemu/-/blob/master/tests/unit/test-multi-target.c#L35 The init sequence is quite straightforward: ``` /* initialize target types, and only them */ module_call_init(MODULE_INIT_TARGET_INFO); /* we can get the list if we want, for -target or any other purpose */ g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false); /* set the global target info from any element in this list */ TargetInfo* ti = ...; target_info_qom_set_target_info(ti); /* register rest of QOM types */ module_call_init(MODULE_INIT_QOM); ``` It works fine to implement -target (if we would like to do it), since I implemented it myself. That was also my initial motivation by the way. Also, I appreciate that target-info is NULL by default, it crashes loudly when it has not been set, and make it easy to find who depends on it. > If we treat target_info as a QOM, but QOM needs target_info to set > up(is_avaible). That makes > the init sequence too much of a burden. > See sequence above, the solution is to initialize TARGET_INFO first, before the rest of QOM. You end up with the same result than with a statically initialized list. > > is_available is depends on target_arch > And before this patch, target_arch depends on QOM, pulls user/softmmu because > target_info_init. By moving target-info to be a custom list based, we > can decouple > target-info from qom/softmmu/user. and target-info will always > available once "main(argv, argc)" is entered. We also have the > advantage of doing all sorts > of tests against it. > Which kind of tests are you trying to add? For now, the exact list of places where we need to do this initialize target dance are: - system/vl.c: module_call_init(MODULE_INIT_TARGET_INFO); - tests/qtest/fuzz/fuzz.c: module_call_init(MODULE_INIT_TARGET_INFO); - tests/unit/test-multi-target.c: module_call_init(MODULE_INIT_TARGET_INFO); If we want more tests, I'm totally ok to move this init code to target-info.c, and replace call sites if needed. > > Tools such as qemu-img and unit tests may link target-info.c without any > target-info-def.c objects. Their target list remains empty, so use this > fallback. > Why should this tool get access to target list? qemu-img deals with disk images, and is unrelated to targets. > > static TypeImpl *type_register_internal(const TypeInfo *info) > { > TypeImpl *ti; > > if (!type_name_is_valid(info->name)) { > fprintf(stderr, "Registering '%s' with illegal type name\n", > info->name); > abort(); > } > > if (info->is_available && !info->is_available()) { > return NULL; > } > > ti = type_new(info); > > type_table_add(ti); > return ti; > } > >> >> Is there another good value this list approach brings compared to what >> exists? >> >> Regards, >> Pierrick > > > ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-07 22:31 ` Pierrick Bouvier @ 2026-10-07 22:54 ` Yonggang Luo 2026-10-07 23:24 ` Pierrick Bouvier 2026-10-07 23:02 ` Yonggang Luo 1 sibling, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-07 22:54 UTC (permalink / raw) To: Pierrick Bouvier Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Thu, Oct 8, 2026 at 6:31 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/7/2026 1:50 PM, Yonggang Luo wrote: > > On Thu, Oct 8, 2026 at 4:29 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> wrote: > >> > >> On 10/7/2026 4:48 AM, Yonggang Luo wrote: > >>> Register target definitions through constructors instead of > >>> MODULE_INIT_TARGET_INFO, making target_info_list() and target_info() > >>> available on entry to main(), without explicit initialization or a > >>> call to module_call_init(MODULE_INIT_QOM). > >>> > >>> Keep the target list sorted by target_arch and default to its first > >>> entry. Provide an unknown TargetInfo fallback for target-independent > >>> tools such as qemu-img and unit tests that link no target-info-def.c > >>> objects. > >>> > >>> Remove the obsolete QOM target-info registration infrastructure and > >>> update the multi-target test to inspect target information before > >>> initializing QOM. > >>> > >>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > >>> --- > >>> include/qemu/module.h | 1 - > >>> include/qemu/target-info-def.h | 56 +++++++++++++++++++++++++++--- > >>> include/qemu/target-info-init.h | 53 ---------------------------- > >>> include/qemu/target-info-qom.h | 31 ----------------- > >>> include/qemu/target-info.h | 9 +++++ > >>> meson.build | 6 ++-- > >>> system/vl.c | 4 --- > >>> target-info-def.c | 1 - > >>> target-info-qom.c | 60 -------------------------------- > >>> target-info.c | 61 ++++++++++++++++++++++++++++++++- > >>> tests/qtest/fuzz/fuzz.c | 3 -- > >>> tests/unit/test-multi-target.c | 12 +++---- > >>> 12 files changed, 129 insertions(+), 168 deletions(-) > >>> delete mode 100644 include/qemu/target-info-init.h > >>> delete mode 100644 include/qemu/target-info-qom.h > >>> delete mode 100644 target-info-qom.c > >>> > >> > >> This approach (custom list based) was considered before implementing > >> things with QOM Types. The rationale I followed was that if everything > >> is in QOM, we might better follow that for consistency sake. > >> Yes, the compromise if that we need an extra init step, but it was not a > >> problem to add it. > > I have issue to add the init step for unit-tests, and hard to write the -target > > parse procedure and get it right. Not means this won't work. but for > > me, too much > > coupled. > > > > We already have such a test upstream: > https://gitlab.com/qemu-project/qemu/-/blob/master/tests/unit/test-multi-target.c#L35 > > The init sequence is quite straightforward: > > ``` > /* initialize target types, and only them */ > module_call_init(MODULE_INIT_TARGET_INFO); > > /* we can get the list if we want, for -target or any other purpose */ > g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false); > > /* set the global target info from any element in this list */ > TargetInfo* ti = ...; > target_info_qom_set_target_info(ti); > > /* register rest of QOM types */ > module_call_init(MODULE_INIT_QOM); > ``` > > It works fine to implement -target (if we would like to do it), since I > implemented it myself. That was also my initial motivation by the way. > > Also, I appreciate that target-info is NULL by default, it crashes > loudly when it has not been set, and make it easy to find who depends on it. > > > If we treat target_info as a QOM, but QOM needs target_info to set > > up(is_avaible). That makes > > the init sequence too much of a burden. > > > > See sequence above, the solution is to initialize TARGET_INFO first, > before the rest of QOM. You end up with the same result than with a > statically initialized list. > > > > > is_available is depends on target_arch > > And before this patch, target_arch depends on QOM, pulls user/softmmu because > > target_info_init. By moving target-info to be a custom list based, we > > can decouple > > target-info from qom/softmmu/user. and target-info will always > > available once "main(argv, argc)" is entered. We also have the > > advantage of doing all sorts > > of tests against it. > > > > Which kind of tests are you trying to add? > > For now, the exact list of places where we need to do this initialize > target dance are: > - system/vl.c: module_call_init(MODULE_INIT_TARGET_INFO); > - tests/qtest/fuzz/fuzz.c: module_call_init(MODULE_INIT_TARGET_INFO); > - tests/unit/test-multi-target.c: > module_call_init(MODULE_INIT_TARGET_INFO); > > If we want more tests, I'm totally ok to move this init code to > target-info.c, and replace call sites if needed. > > > > > Tools such as qemu-img and unit tests may link target-info.c without any > > target-info-def.c objects. Their target list remains empty, so use this > > fallback. > > > > Why should this tool get access to target list? qemu-img deals with disk > images, and is unrelated to targets. > > > > > static TypeImpl *type_register_internal(const TypeInfo *info) > > { > > TypeImpl *ti; > > > > if (!type_name_is_valid(info->name)) { > > fprintf(stderr, "Registering '%s' with illegal type name\n", > > info->name); > > abort(); > > } > > > > if (info->is_available && !info->is_available()) { > > return NULL; > > } > > > > ti = type_new(info); > > > > type_table_add(ti); > > return ti; > > } > > > >> > >> Is there another good value this list approach brings compared to what > >> exists? Sorry, I have to wait for your work to be done first. I have too many patches depending on this, and it seems hard to convince you. Let's just keep it as is. Maybe you can work them out in an easier way. My work is here. https://gitlab.com/lygstate-qemu/qemu/-/tree/combined-binary-multi-targets?ref_type=heads I am afraid of posting 300 pathces into threads to flood it(and disturbing yours). So I'll wait for your work first. and resolving conflicts later, that's really time-consuming. I did many explanations before. seems my explanation is too bad and not to give a clean picture for you, let's delay these first. I only sent these 8 patches for easier review. because too many patches won't be accepted either. > >> > >> Regards, > >> Pierrick > > > > > > > -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-07 22:54 ` Yonggang Luo @ 2026-10-07 23:24 ` Pierrick Bouvier 2026-10-13 9:26 ` Daniel P. Berrangé 0 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-07 23:24 UTC (permalink / raw) To: luoyonggang Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/7/2026 3:54 PM, Yonggang Luo wrote: > On Thu, Oct 8, 2026 at 6:31 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> wrote: >> >> On 10/7/2026 1:50 PM, Yonggang Luo wrote: >>> On Thu, Oct 8, 2026 at 4:29 AM Pierrick Bouvier >>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>> >>>> On 10/7/2026 4:48 AM, Yonggang Luo wrote: >>>>> Register target definitions through constructors instead of >>>>> MODULE_INIT_TARGET_INFO, making target_info_list() and target_info() >>>>> available on entry to main(), without explicit initialization or a >>>>> call to module_call_init(MODULE_INIT_QOM). >>>>> >>>>> Keep the target list sorted by target_arch and default to its first >>>>> entry. Provide an unknown TargetInfo fallback for target-independent >>>>> tools such as qemu-img and unit tests that link no target-info-def.c >>>>> objects. >>>>> >>>>> Remove the obsolete QOM target-info registration infrastructure and >>>>> update the multi-target test to inspect target information before >>>>> initializing QOM. >>>>> >>>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> >>>>> --- >>>>> include/qemu/module.h | 1 - >>>>> include/qemu/target-info-def.h | 56 +++++++++++++++++++++++++++--- >>>>> include/qemu/target-info-init.h | 53 ---------------------------- >>>>> include/qemu/target-info-qom.h | 31 ----------------- >>>>> include/qemu/target-info.h | 9 +++++ >>>>> meson.build | 6 ++-- >>>>> system/vl.c | 4 --- >>>>> target-info-def.c | 1 - >>>>> target-info-qom.c | 60 -------------------------------- >>>>> target-info.c | 61 ++++++++++++++++++++++++++++++++- >>>>> tests/qtest/fuzz/fuzz.c | 3 -- >>>>> tests/unit/test-multi-target.c | 12 +++---- >>>>> 12 files changed, 129 insertions(+), 168 deletions(-) >>>>> delete mode 100644 include/qemu/target-info-init.h >>>>> delete mode 100644 include/qemu/target-info-qom.h >>>>> delete mode 100644 target-info-qom.c >>>>> >>>> >>>> This approach (custom list based) was considered before implementing >>>> things with QOM Types. The rationale I followed was that if everything >>>> is in QOM, we might better follow that for consistency sake. >>>> Yes, the compromise if that we need an extra init step, but it was not a >>>> problem to add it. >>> I have issue to add the init step for unit-tests, and hard to write the -target >>> parse procedure and get it right. Not means this won't work. but for >>> me, too much >>> coupled. >>> >> >> We already have such a test upstream: >> https://gitlab.com/qemu-project/qemu/-/blob/master/tests/unit/test-multi-target.c#L35 >> >> The init sequence is quite straightforward: >> >> ``` >> /* initialize target types, and only them */ >> module_call_init(MODULE_INIT_TARGET_INFO); >> >> /* we can get the list if we want, for -target or any other purpose */ >> g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false); >> >> /* set the global target info from any element in this list */ >> TargetInfo* ti = ...; >> target_info_qom_set_target_info(ti); >> >> /* register rest of QOM types */ >> module_call_init(MODULE_INIT_QOM); >> ``` >> >> It works fine to implement -target (if we would like to do it), since I >> implemented it myself. That was also my initial motivation by the way. >> >> Also, I appreciate that target-info is NULL by default, it crashes >> loudly when it has not been set, and make it easy to find who depends on it. >> >>> If we treat target_info as a QOM, but QOM needs target_info to set >>> up(is_avaible). That makes >>> the init sequence too much of a burden. >>> >> >> See sequence above, the solution is to initialize TARGET_INFO first, >> before the rest of QOM. You end up with the same result than with a >> statically initialized list. >> >>> >>> is_available is depends on target_arch >>> And before this patch, target_arch depends on QOM, pulls user/softmmu because >>> target_info_init. By moving target-info to be a custom list based, we >>> can decouple >>> target-info from qom/softmmu/user. and target-info will always >>> available once "main(argv, argc)" is entered. We also have the >>> advantage of doing all sorts >>> of tests against it. >>> >> >> Which kind of tests are you trying to add? >> >> For now, the exact list of places where we need to do this initialize >> target dance are: >> - system/vl.c: module_call_init(MODULE_INIT_TARGET_INFO); >> - tests/qtest/fuzz/fuzz.c: module_call_init(MODULE_INIT_TARGET_INFO); >> - tests/unit/test-multi-target.c: >> module_call_init(MODULE_INIT_TARGET_INFO); >> >> If we want more tests, I'm totally ok to move this init code to >> target-info.c, and replace call sites if needed. >> >>> >>> Tools such as qemu-img and unit tests may link target-info.c without any >>> target-info-def.c objects. Their target list remains empty, so use this >>> fallback. >>> >> >> Why should this tool get access to target list? qemu-img deals with disk >> images, and is unrelated to targets. >> >>> >>> static TypeImpl *type_register_internal(const TypeInfo *info) >>> { >>> TypeImpl *ti; >>> >>> if (!type_name_is_valid(info->name)) { >>> fprintf(stderr, "Registering '%s' with illegal type name\n", >>> info->name); >>> abort(); >>> } >>> >>> if (info->is_available && !info->is_available()) { >>> return NULL; >>> } >>> >>> ti = type_new(info); >>> >>> type_table_add(ti); >>> return ti; >>> } >>> >>>> >>>> Is there another good value this list approach brings compared to what >>>> exists? > > Sorry, I have to wait for your work to be done first. > I have too many patches depending on this, and it seems hard to > convince you. Let's just keep it as is. > Maybe you can work them out in an easier way. > I quit the effort of upstreaming a qemu-system binary some time ago, because it was not easy to get a consensus on what the new binary should be, and I'm happy you took the relay there. I try my best to help on the issues you bring, some of them being interesting problems that we need to solve. Thanks to your work and persistence, it seems like conversation is starting to converge towards something: qemu-system with all devices/machines/cpus available. It's not what I had in my mind originally, but I'm happy to see progress on this, and open to accept this alternative! > My work is here. > https://gitlab.com/lygstate-qemu/qemu/-/tree/combined-binary-multi-targets?ref_type=heads > I am afraid of posting 300 pathces into threads to flood it(and > disturbing yours). So I'll wait for your work first. and resolving > conflicts later, that's really time-consuming. > It's indeed not possible to send 300 patches and expect this to work, whether it's on this mailing list, or any software forge also. It's also not possible to send a link, and expect anyone to take a look at the 373 commits sitting it on top of master. My name is not Claude. Instead, humans have to progress step by step, based on feedback. Yes it takes time and it can be frustrating. And yes, I've been there (and frustrated) also, I feel sorry for you. At the moment, if we want to make it move on, we need to focus on one single thing: "How to document/specify which targets a machine support". > I did many explanations before. seems my explanation is too bad and > not to give a clean picture for you, let's delay these first. > If I can suggest something politely here, IMHO, alternating between genuinely human written messages, and AI content sent as it is on email or commit messages is not helping on the receiver side. I would prefer anytime to deal with imperfect english (mine is imperfect too, I'm not a native speaker neither), compared to read what Claude/GPT/Deepseek generated that was pasted as it is. I understand it's a good tool for helping on the language side, and that's ok to fix grammar and sentence structure. But asking "Please generate a summary from those email threads and explain what the current series is doing", and paste this is doomed to fail. It also has a very detrimental side effect: it makes me start to wonder where the code is coming from also. Especially when seeing boilerplates with lengthy comments written in perfect english. My 2 cents is, use AI if you want/need, but make sure the result has this *human* touch. > I only sent these 8 patches for easier review. because too many > patches won't be accepted either. > This series is useful, thanks to your answer on last patch, I finally see where you're headed. I'll answer there to keep this moving forward. Regards, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-07 23:24 ` Pierrick Bouvier @ 2026-10-13 9:26 ` Daniel P. Berrangé 2026-10-13 15:53 ` Pierrick Bouvier 0 siblings, 1 reply; 62+ messages in thread From: Daniel P. Berrangé @ 2026-10-13 9:26 UTC (permalink / raw) To: Pierrick Bouvier Cc: luoyonggang, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Wed, Oct 07, 2026 at 04:24:07PM -0700, Pierrick Bouvier wrote: > On 10/7/2026 3:54 PM, Yonggang Luo wrote: > > My work is here. > > https://gitlab.com/lygstate-qemu/qemu/-/tree/combined-binary-multi-targets?ref_type=heads > > I am afraid of posting 300 pathces into threads to flood it(and > > disturbing yours). So I'll wait for your work first. and resolving > > conflicts later, that's really time-consuming. > > > > It's indeed not possible to send 300 patches and expect this to work, > whether it's on this mailing list, or any software forge also. > It's also not possible to send a link, and expect anyone to take a look > at the 373 commits sitting it on top of master. My name is not Claude. > Instead, humans have to progress step by step, based on feedback. Yes it > takes time and it can be frustrating. And yes, I've been there (and > frustrated) also, I feel sorry for you. > > At the moment, if we want to make it move on, we need to focus on one > single thing: > "How to document/specify which targets a machine support". > > > I did many explanations before. seems my explanation is too bad and > > not to give a clean picture for you, let's delay these first. > > > > If I can suggest something politely here, IMHO, alternating between > genuinely human written messages, and AI content sent as it is on email > or commit messages is not helping on the receiver side. > > I would prefer anytime to deal with imperfect english (mine is imperfect > too, I'm not a native speaker neither), compared to read what > Claude/GPT/Deepseek generated that was pasted as it is. > I understand it's a good tool for helping on the language side, and > that's ok to fix grammar and sentence structure. > But asking "Please generate a summary from those email threads and > explain what the current series is doing", and paste this is doomed to fail. > > It also has a very detrimental side effect: it makes me start to wonder > where the code is coming from also. Especially when seeing boilerplates > with lengthy comments written in perfect english. My 2 cents is, use AI > if you want/need, but make sure the result has this *human* touch. Although these are not yet final/commited, please bear in mind the proposed updated AI guidelines which broadly intend to forbid use of AI for authoring commit messages & cover letters: https://lists.gnu.org/archive/html/qemu-devel/2026-09/msg00260.html With regards, Daniel -- |: https://berrange.com ~~ https://hachyderm.io/@berrange :| |: https://libvirt.org ~~ https://entangle-photo.org :| |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :| ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-13 9:26 ` Daniel P. Berrangé @ 2026-10-13 15:53 ` Pierrick Bouvier 0 siblings, 0 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-13 15:53 UTC (permalink / raw) To: Daniel P. Berrangé Cc: luoyonggang, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/13/2026 2:26 AM, Daniel P. Berrangé wrote: > On Wed, Oct 07, 2026 at 04:24:07PM -0700, Pierrick Bouvier wrote: >> On 10/7/2026 3:54 PM, Yonggang Luo wrote: >>> My work is here. >>> https://gitlab.com/lygstate-qemu/qemu/-/tree/combined-binary-multi-targets?ref_type=heads >>> I am afraid of posting 300 pathces into threads to flood it(and >>> disturbing yours). So I'll wait for your work first. and resolving >>> conflicts later, that's really time-consuming. >>> >> >> It's indeed not possible to send 300 patches and expect this to work, >> whether it's on this mailing list, or any software forge also. >> It's also not possible to send a link, and expect anyone to take a look >> at the 373 commits sitting it on top of master. My name is not Claude. >> Instead, humans have to progress step by step, based on feedback. Yes it >> takes time and it can be frustrating. And yes, I've been there (and >> frustrated) also, I feel sorry for you. >> >> At the moment, if we want to make it move on, we need to focus on one >> single thing: >> "How to document/specify which targets a machine support". >> >>> I did many explanations before. seems my explanation is too bad and >>> not to give a clean picture for you, let's delay these first. >>> >> >> If I can suggest something politely here, IMHO, alternating between >> genuinely human written messages, and AI content sent as it is on email >> or commit messages is not helping on the receiver side. >> >> I would prefer anytime to deal with imperfect english (mine is imperfect >> too, I'm not a native speaker neither), compared to read what >> Claude/GPT/Deepseek generated that was pasted as it is. >> I understand it's a good tool for helping on the language side, and >> that's ok to fix grammar and sentence structure. >> But asking "Please generate a summary from those email threads and >> explain what the current series is doing", and paste this is doomed to fail. >> >> It also has a very detrimental side effect: it makes me start to wonder >> where the code is coming from also. Especially when seeing boilerplates >> with lengthy comments written in perfect english. My 2 cents is, use AI >> if you want/need, but make sure the result has this *human* touch. > > Although these are not yet final/commited, please bear in mind the > proposed updated AI guidelines which broadly intend to forbid use > of AI for authoring commit messages & cover letters: > > https://lists.gnu.org/archive/html/qemu-devel/2026-09/msg00260.html > While the AI discussion is on going, maybe it would be nice to forbid that on the mailing list also. > > With regards, > Daniel ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-07 22:31 ` Pierrick Bouvier 2026-10-07 22:54 ` Yonggang Luo @ 2026-10-07 23:02 ` Yonggang Luo 2026-10-07 23:28 ` Pierrick Bouvier 1 sibling, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-07 23:02 UTC (permalink / raw) To: Pierrick Bouvier Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Thu, Oct 8, 2026 at 6:31 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/7/2026 1:50 PM, Yonggang Luo wrote: > > On Thu, Oct 8, 2026 at 4:29 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> wrote: > >> > >> On 10/7/2026 4:48 AM, Yonggang Luo wrote: > >>> Register target definitions through constructors instead of > >>> MODULE_INIT_TARGET_INFO, making target_info_list() and target_info() > >>> available on entry to main(), without explicit initialization or a > >>> call to module_call_init(MODULE_INIT_QOM). > >>> > >>> Keep the target list sorted by target_arch and default to its first > >>> entry. Provide an unknown TargetInfo fallback for target-independent > >>> tools such as qemu-img and unit tests that link no target-info-def.c > >>> objects. > >>> > >>> Remove the obsolete QOM target-info registration infrastructure and > >>> update the multi-target test to inspect target information before > >>> initializing QOM. > >>> > >>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > >>> --- > >>> include/qemu/module.h | 1 - > >>> include/qemu/target-info-def.h | 56 +++++++++++++++++++++++++++--- > >>> include/qemu/target-info-init.h | 53 ---------------------------- > >>> include/qemu/target-info-qom.h | 31 ----------------- > >>> include/qemu/target-info.h | 9 +++++ > >>> meson.build | 6 ++-- > >>> system/vl.c | 4 --- > >>> target-info-def.c | 1 - > >>> target-info-qom.c | 60 -------------------------------- > >>> target-info.c | 61 ++++++++++++++++++++++++++++++++- > >>> tests/qtest/fuzz/fuzz.c | 3 -- > >>> tests/unit/test-multi-target.c | 12 +++---- > >>> 12 files changed, 129 insertions(+), 168 deletions(-) > >>> delete mode 100644 include/qemu/target-info-init.h > >>> delete mode 100644 include/qemu/target-info-qom.h > >>> delete mode 100644 target-info-qom.c > >>> > >> > >> This approach (custom list based) was considered before implementing > >> things with QOM Types. The rationale I followed was that if everything > >> is in QOM, we might better follow that for consistency sake. > >> Yes, the compromise if that we need an extra init step, but it was not a > >> problem to add it. > > I have issue to add the init step for unit-tests, and hard to write the -target > > parse procedure and get it right. Not means this won't work. but for > > me, too much > > coupled. > > > > We already have such a test upstream: > https://gitlab.com/qemu-project/qemu/-/blob/master/tests/unit/test-multi-target.c#L35 > > The init sequence is quite straightforward: > > ``` > /* initialize target types, and only them */ > module_call_init(MODULE_INIT_TARGET_INFO); > > /* we can get the list if we want, for -target or any other purpose */ > g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false); > > /* set the global target info from any element in this list */ > TargetInfo* ti = ...; > target_info_qom_set_target_info(ti); > > /* register rest of QOM types */ > module_call_init(MODULE_INIT_QOM); > ``` > > It works fine to implement -target (if we would like to do it), since I > implemented it myself. That was also my initial motivation by the way. > > Also, I appreciate that target-info is NULL by default, it crashes > loudly when it has not been set, and make it easy to find who depends on it. > > > If we treat target_info as a QOM, but QOM needs target_info to set > > up(is_avaible). That makes > > the init sequence too much of a burden. > > > > See sequence above, the solution is to initialize TARGET_INFO first, > before the rest of QOM. You end up with the same result than with a > statically initialized list. > > > > > is_available is depends on target_arch > > And before this patch, target_arch depends on QOM, pulls user/softmmu because > > target_info_init. By moving target-info to be a custom list based, we > > can decouple > > target-info from qom/softmmu/user. and target-info will always > > available once "main(argv, argc)" is entered. We also have the > > advantage of doing all sorts > > of tests against it. > > > > Which kind of tests are you trying to add? > > For now, the exact list of places where we need to do this initialize > target dance are: > - system/vl.c: module_call_init(MODULE_INIT_TARGET_INFO); > - tests/qtest/fuzz/fuzz.c: module_call_init(MODULE_INIT_TARGET_INFO); > - tests/unit/test-multi-target.c: # Multi targets test if multi_target_objects != [] test('test-multi-target', executable('test-multi-target', sources: [multi_target_crates, files('test-multi-target.c')], dependencies: multi_target_deps, objects: multi_target_objects, link_depends: [block_syms, qemu_syms], link_args: multi_target_link_args), suite: ['unit']) endif I see this test, I am trying to add tests that do not pull so many multi_target_objects, as it would be huge. Just pull qom only. And I am trying to call target_info() in object.c, as inspect machines with qemu-system is rejected, so maybe that's not an issue anymore I means Subject: [PATCH v3 00/10] machine: uniquify virt QOM names https://lore.kernel.org/qemu-devel/20260926081551.29-1-luoyonggang@gmail.com/#r So the current design always rejects types that do not belong to the current target. Listing them all is not an option at all. With this restriction, then these are indeed not needed. So I'll wait for your work first, otherwise it's always conflicting. > module_call_init(MODULE_INIT_TARGET_INFO); > > If we want more tests, I'm totally ok to move this init code to > target-info.c, and replace call sites if needed. > > > > > Tools such as qemu-img and unit tests may link target-info.c without any > > target-info-def.c objects. Their target list remains empty, so use this > > fallback. > > > > Why should this tool get access to target list? qemu-img deals with disk > images, and is unrelated to targets. > > > > > static TypeImpl *type_register_internal(const TypeInfo *info) > > { > > TypeImpl *ti; > > > > if (!type_name_is_valid(info->name)) { > > fprintf(stderr, "Registering '%s' with illegal type name\n", > > info->name); > > abort(); > > } > > > > if (info->is_available && !info->is_available()) { > > return NULL; > > } > > > > ti = type_new(info); > > > > type_table_add(ti); > > return ti; > > } > > > >> > >> Is there another good value this list approach brings compared to what > >> exists? > >> > >> Regards, > >> Pierrick > > > > > > > -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-07 23:02 ` Yonggang Luo @ 2026-10-07 23:28 ` Pierrick Bouvier 2026-10-12 21:27 ` Yonggang Luo 0 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-07 23:28 UTC (permalink / raw) To: luoyonggang Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/7/2026 4:02 PM, Yonggang Luo wrote: > On Thu, Oct 8, 2026 at 6:31 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> wrote: >> >> On 10/7/2026 1:50 PM, Yonggang Luo wrote: >>> On Thu, Oct 8, 2026 at 4:29 AM Pierrick Bouvier >>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>> >>>> On 10/7/2026 4:48 AM, Yonggang Luo wrote: >>>>> Register target definitions through constructors instead of >>>>> MODULE_INIT_TARGET_INFO, making target_info_list() and target_info() >>>>> available on entry to main(), without explicit initialization or a >>>>> call to module_call_init(MODULE_INIT_QOM). >>>>> >>>>> Keep the target list sorted by target_arch and default to its first >>>>> entry. Provide an unknown TargetInfo fallback for target-independent >>>>> tools such as qemu-img and unit tests that link no target-info-def.c >>>>> objects. >>>>> >>>>> Remove the obsolete QOM target-info registration infrastructure and >>>>> update the multi-target test to inspect target information before >>>>> initializing QOM. >>>>> >>>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> >>>>> --- >>>>> include/qemu/module.h | 1 - >>>>> include/qemu/target-info-def.h | 56 +++++++++++++++++++++++++++--- >>>>> include/qemu/target-info-init.h | 53 ---------------------------- >>>>> include/qemu/target-info-qom.h | 31 ----------------- >>>>> include/qemu/target-info.h | 9 +++++ >>>>> meson.build | 6 ++-- >>>>> system/vl.c | 4 --- >>>>> target-info-def.c | 1 - >>>>> target-info-qom.c | 60 -------------------------------- >>>>> target-info.c | 61 ++++++++++++++++++++++++++++++++- >>>>> tests/qtest/fuzz/fuzz.c | 3 -- >>>>> tests/unit/test-multi-target.c | 12 +++---- >>>>> 12 files changed, 129 insertions(+), 168 deletions(-) >>>>> delete mode 100644 include/qemu/target-info-init.h >>>>> delete mode 100644 include/qemu/target-info-qom.h >>>>> delete mode 100644 target-info-qom.c >>>>> >>>> >>>> This approach (custom list based) was considered before implementing >>>> things with QOM Types. The rationale I followed was that if everything >>>> is in QOM, we might better follow that for consistency sake. >>>> Yes, the compromise if that we need an extra init step, but it was not a >>>> problem to add it. >>> I have issue to add the init step for unit-tests, and hard to write the -target >>> parse procedure and get it right. Not means this won't work. but for >>> me, too much >>> coupled. >>> >> >> We already have such a test upstream: >> https://gitlab.com/qemu-project/qemu/-/blob/master/tests/unit/test-multi-target.c#L35 >> >> The init sequence is quite straightforward: >> >> ``` >> /* initialize target types, and only them */ >> module_call_init(MODULE_INIT_TARGET_INFO); >> >> /* we can get the list if we want, for -target or any other purpose */ >> g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false); >> >> /* set the global target info from any element in this list */ >> TargetInfo* ti = ...; >> target_info_qom_set_target_info(ti); >> >> /* register rest of QOM types */ >> module_call_init(MODULE_INIT_QOM); >> ``` >> >> It works fine to implement -target (if we would like to do it), since I >> implemented it myself. That was also my initial motivation by the way. >> >> Also, I appreciate that target-info is NULL by default, it crashes >> loudly when it has not been set, and make it easy to find who depends on it. >> >>> If we treat target_info as a QOM, but QOM needs target_info to set >>> up(is_avaible). That makes >>> the init sequence too much of a burden. >>> >> >> See sequence above, the solution is to initialize TARGET_INFO first, >> before the rest of QOM. You end up with the same result than with a >> statically initialized list. >> >>> >>> is_available is depends on target_arch >>> And before this patch, target_arch depends on QOM, pulls user/softmmu because >>> target_info_init. By moving target-info to be a custom list based, we >>> can decouple >>> target-info from qom/softmmu/user. and target-info will always >>> available once "main(argv, argc)" is entered. We also have the >>> advantage of doing all sorts >>> of tests against it. >>> >> >> Which kind of tests are you trying to add? >> >> For now, the exact list of places where we need to do this initialize >> target dance are: >> - system/vl.c: module_call_init(MODULE_INIT_TARGET_INFO); >> - tests/qtest/fuzz/fuzz.c: module_call_init(MODULE_INIT_TARGET_INFO); >> - tests/unit/test-multi-target.c: > > # Multi targets test > if multi_target_objects != [] > test('test-multi-target', > executable('test-multi-target', > sources: [multi_target_crates, files('test-multi-target.c')], > dependencies: multi_target_deps, > objects: multi_target_objects, > link_depends: [block_syms, qemu_syms], > link_args: multi_target_link_args), > suite: ['unit']) > endif > > I see this test, I am trying to add tests that do not pull so many > multi_target_objects, as it would be huge. Agree, we should not add more binary. If you need truly multi targets test, this existing binary is a good place to start: just add a second test in it. > Just pull qom only. And I am trying to call target_info() in > object.c, as inspect machines with > qemu-system is rejected, so maybe that's not an issue anymore > Seems like a good candidate for the multi-target.c test. > > I means Subject: [PATCH v3 00/10] machine: uniquify virt QOM names > https://lore.kernel.org/qemu-devel/20260926081551.29-1-luoyonggang@gmail.com/#r > > So the current design always rejects types that do not belong to the > current target. Listing them > all is not an option at all. With this restriction, then these are > indeed not needed. > So I'll wait for your work first, otherwise it's always conflicting. > > >> module_call_init(MODULE_INIT_TARGET_INFO); >> >> If we want more tests, I'm totally ok to move this init code to >> target-info.c, and replace call sites if needed. >> >>> >>> Tools such as qemu-img and unit tests may link target-info.c without any >>> target-info-def.c objects. Their target list remains empty, so use this >>> fallback. >>> >> >> Why should this tool get access to target list? qemu-img deals with disk >> images, and is unrelated to targets. >> >>> >>> static TypeImpl *type_register_internal(const TypeInfo *info) >>> { >>> TypeImpl *ti; >>> >>> if (!type_name_is_valid(info->name)) { >>> fprintf(stderr, "Registering '%s' with illegal type name\n", >>> info->name); >>> abort(); >>> } >>> >>> if (info->is_available && !info->is_available()) { >>> return NULL; >>> } >>> >>> ti = type_new(info); >>> >>> type_table_add(ti); >>> return ti; >>> } >>> >>>> >>>> Is there another good value this list approach brings compared to what >>>> exists? >>>> >>>> Regards, >>>> Pierrick >>> >>> >>> >> > > ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-07 23:28 ` Pierrick Bouvier @ 2026-10-12 21:27 ` Yonggang Luo 2026-10-13 3:57 ` Pierrick Bouvier 0 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-12 21:27 UTC (permalink / raw) To: Pierrick Bouvier Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Thu, Oct 8, 2026 at 7:28 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/7/2026 4:02 PM, Yonggang Luo wrote: > > On Thu, Oct 8, 2026 at 6:31 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> wrote: > >> > >> On 10/7/2026 1:50 PM, Yonggang Luo wrote: > >>> On Thu, Oct 8, 2026 at 4:29 AM Pierrick Bouvier > >>> <pierrick.bouvier@oss.qualcomm.com> wrote: > >>>> > >>>> On 10/7/2026 4:48 AM, Yonggang Luo wrote: > >>>>> Register target definitions through constructors instead of > >>>>> MODULE_INIT_TARGET_INFO, making target_info_list() and target_info() > >>>>> available on entry to main(), without explicit initialization or a > >>>>> call to module_call_init(MODULE_INIT_QOM). > >>>>> > >>>>> Keep the target list sorted by target_arch and default to its first > >>>>> entry. Provide an unknown TargetInfo fallback for target-independent > >>>>> tools such as qemu-img and unit tests that link no target-info-def.c > >>>>> objects. > >>>>> > >>>>> Remove the obsolete QOM target-info registration infrastructure and > >>>>> update the multi-target test to inspect target information before > >>>>> initializing QOM. > >>>>> > >>>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > >>>>> --- > >>>>> include/qemu/module.h | 1 - > >>>>> include/qemu/target-info-def.h | 56 +++++++++++++++++++++++++++--- > >>>>> include/qemu/target-info-init.h | 53 ---------------------------- > >>>>> include/qemu/target-info-qom.h | 31 ----------------- > >>>>> include/qemu/target-info.h | 9 +++++ > >>>>> meson.build | 6 ++-- > >>>>> system/vl.c | 4 --- > >>>>> target-info-def.c | 1 - > >>>>> target-info-qom.c | 60 -------------------------------- > >>>>> target-info.c | 61 ++++++++++++++++++++++++++++++++- > >>>>> tests/qtest/fuzz/fuzz.c | 3 -- > >>>>> tests/unit/test-multi-target.c | 12 +++---- > >>>>> 12 files changed, 129 insertions(+), 168 deletions(-) > >>>>> delete mode 100644 include/qemu/target-info-init.h > >>>>> delete mode 100644 include/qemu/target-info-qom.h > >>>>> delete mode 100644 target-info-qom.c > >>>>> > >>>> > >>>> This approach (custom list based) was considered before implementing > >>>> things with QOM Types. The rationale I followed was that if everything > >>>> is in QOM, we might better follow that for consistency sake. > >>>> Yes, the compromise if that we need an extra init step, but it was not a > >>>> problem to add it. > >>> I have issue to add the init step for unit-tests, and hard to write the -target > >>> parse procedure and get it right. Not means this won't work. but for > >>> me, too much > >>> coupled. > >>> > >> > >> We already have such a test upstream: > >> https://gitlab.com/qemu-project/qemu/-/blob/master/tests/unit/test-multi-target.c#L35 > >> > >> The init sequence is quite straightforward: > >> > >> ``` > >> /* initialize target types, and only them */ > >> module_call_init(MODULE_INIT_TARGET_INFO); > >> > >> /* we can get the list if we want, for -target or any other purpose */ > >> g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false); > >> > >> /* set the global target info from any element in this list */ > >> TargetInfo* ti = ...; > >> target_info_qom_set_target_info(ti); > >> > >> /* register rest of QOM types */ > >> module_call_init(MODULE_INIT_QOM); > >> ``` > >> > >> It works fine to implement -target (if we would like to do it), since I > >> implemented it myself. That was also my initial motivation by the way. > >> > >> Also, I appreciate that target-info is NULL by default, it crashes > >> loudly when it has not been set, and make it easy to find who depends on it. > >> > >>> If we treat target_info as a QOM, but QOM needs target_info to set > >>> up(is_avaible). That makes > >>> the init sequence too much of a burden. > >>> > >> > >> See sequence above, the solution is to initialize TARGET_INFO first, > >> before the rest of QOM. You end up with the same result than with a > >> statically initialized list. > >> > >>> > >>> is_available is depends on target_arch > >>> And before this patch, target_arch depends on QOM, pulls user/softmmu because > >>> target_info_init. By moving target-info to be a custom list based, we > >>> can decouple > >>> target-info from qom/softmmu/user. and target-info will always > >>> available once "main(argv, argc)" is entered. We also have the > >>> advantage of doing all sorts > >>> of tests against it. > >>> > >> > >> Which kind of tests are you trying to add? > >> > >> For now, the exact list of places where we need to do this initialize > >> target dance are: > >> - system/vl.c: module_call_init(MODULE_INIT_TARGET_INFO); > >> - tests/qtest/fuzz/fuzz.c: module_call_init(MODULE_INIT_TARGET_INFO); > >> - tests/unit/test-multi-target.c: > > > > # Multi targets test > > if multi_target_objects != [] > > test('test-multi-target', > > executable('test-multi-target', > > sources: [multi_target_crates, files('test-multi-target.c')], > > dependencies: multi_target_deps, > > objects: multi_target_objects, > > link_depends: [block_syms, qemu_syms], > > link_args: multi_target_link_args), > > suite: ['unit']) > > endif > > > > I see this test, I am trying to add tests that do not pull so many > > multi_target_objects, as it would be huge. > > Agree, we should not add more binary. > If you need truly multi targets test, this existing binary is a good > place to start: just add a second test in it. > > > Just pull qom only. And I am trying to call target_info() in > > object.c, as inspect machines with > > qemu-system is rejected, so maybe that's not an issue anymore > > > > Seems like a good candidate for the multi-target.c test. > > > > > I means Subject: [PATCH v3 00/10] machine: uniquify virt QOM names > > https://lore.kernel.org/qemu-devel/20260926081551.29-1-luoyonggang@gmail.com/#r > > > > So the current design always rejects types that do not belong to the > > current target. Listing them > > all is not an option at all. With this restriction, then these are > > indeed not needed. > > So I'll wait for your work first, otherwise it's always conflicting. > > > > > >> module_call_init(MODULE_INIT_TARGET_INFO); > >> > >> If we want more tests, I'm totally ok to move this init code to > >> target-info.c, and replace call sites if needed. > >> > >>> > >>> Tools such as qemu-img and unit tests may link target-info.c without any > >>> target-info-def.c objects. Their target list remains empty, so use this > >>> fallback. > >>> > >> > >> Why should this tool get access to target list? qemu-img deals with disk > >> images, and is unrelated to targets. > >> > >>> > >>> static TypeImpl *type_register_internal(const TypeInfo *info) > >>> { > >>> TypeImpl *ti; > >>> > >>> if (!type_name_is_valid(info->name)) { > >>> fprintf(stderr, "Registering '%s' with illegal type name\n", > >>> info->name); > >>> abort(); > >>> } > >>> > >>> if (info->is_available && !info->is_available()) { > >>> return NULL; > >>> } > >>> > >>> ti = type_new(info); > >>> > >>> type_table_add(ti); > >>> return ti; > >>> } > >>> > >>>> > >>>> Is there another good value this list approach brings compared to what > >>>> exists? > >>>> > >>>> Regards, > >>>> Pierrick > >>> > >>> > >>> > >> > > > > > Hi, the cycle dependencies issue happened again, deal with it's a bit nasty, there is workaround, but I think the constructor list is the best, here is the rationale: # Target discovery during QOM registration ## Problem Machine registration needs the list of targets compiled into the binary. Currently, it obtains that list through: ```c object_class_get_list(TYPE_TARGET_INFO, false); ``` Despite the filter, QOM initializes every registered type before checking whether it implements the requested type. During `MODULE_INIT_QOM`, registration is only partially complete. A device may already be registered while its parent's registration callback has not run, causing failures such as: ```text Type 'sys-bus-device' is missing its parent 'device' ``` The parent is linked into the binary. The problem is premature initialization, not a missing library. ## Option 1: cache target-info QOM classes Enumerate target-info classes once, before device registration starts. Machine registration then reads the cache instead of enumerating QOM. ### Demo Declare shared helpers: ```c void target_info_qom_init(void); const GSList *target_info_qom_get_targets(void); ``` Implement the cache: ```c static GSList *target_info_classes; static bool target_info_initialized; void target_info_qom_init(void) { if (target_info_initialized) { return; } module_call_init(MODULE_INIT_TARGET_INFO); target_info_classes = object_class_get_list(TYPE_TARGET_INFO, false); target_info_initialized = true; } const GSList *target_info_qom_get_targets(void) { assert(target_info_initialized); return target_info_classes; } ``` Initialize it before other QOM registration: ```c target_info_qom_init(); module_call_init(MODULE_INIT_QOM); ``` Machine registration uses the borrowed cache: ```c for (const GSList *l = target_info_qom_get_targets(); l; l = l->next) { const TargetInfo *ti = TARGET_INFO_CLASS(l->data)->target_info; machine_register_virt_type_for_target(info, name_suffix, arch_mask, latest, ti); } ``` `target_info_qom_set_target()` should also use the cached list instead of enumerating QOM again. ### Advantages - Preserves the existing QOM-based representation. - Avoids enumeration during incomplete device registration. - Requires relatively small changes. ### Disadvantages - Every relevant executable and test must initialize the cache before starting QOM registration. - `object_class_get_list()` allocates list nodes. - Callers borrow the list, so it cannot be freed while they are using it. - Cleanup is possible after all consumers finish, but requires an explicit lifecycle policy. Keeping the cache until process exit is a lifetime allocation, not inherently an unreachable memory leak. - Target-info types registered after cache creation are not included. - Target discovery remains coupled to QOM class initialization. ## Option 2: constructor-populated TargetInfo registry Each target registers its immutable `TargetInfo` pointer directly. Machine registration later iterates the registry without querying QOM. Use a statically allocated node per target so registration requires no heap allocation. ### Demo Define a registration node and accessors: ```c typedef struct TargetInfoRegistration { const TargetInfo *info; struct TargetInfoRegistration *next; } TargetInfoRegistration; void target_info_register(TargetInfoRegistration *entry); const TargetInfoRegistration *target_info_get_targets(void); ``` Implement the registry in shared code: ```c static TargetInfoRegistration *target_info_targets; void target_info_register(TargetInfoRegistration *entry) { entry->next = target_info_targets; target_info_targets = entry; } const TargetInfoRegistration *target_info_get_targets(void) { return target_info_targets; } ``` Each target's translation unit provides its own static node and constructor. For example: ```c static TargetInfoRegistration target_info_registration = { .info = &target_info_stub, }; static void __attribute__((constructor)) register_target_info(void) { target_info_register(&target_info_registration); } ``` The constructor must run exactly once per node. The existing target-info initialization macro can generate this registration code alongside the QOM registration code; user-mode target-info behavior should remain unchanged. Machine registration consumes the completed registry: ```c for (const TargetInfoRegistration *entry = target_info_get_targets(); entry; entry = entry->next) { machine_register_virt_type_for_target(info, name_suffix, arch_mask, latest, entry->info); } ``` The sequence is: ```text Target constructors register static metadata pointers ↓ Startup constructors finish ↓ Machine registration iterates the completed registry ``` QOM target-info classes can remain available for introspection. ### Advantages - Makes target discovery independent of QOM initialization. - Removes the explicit cache-initialization step from executables and tests. - Avoids premature initialization of unrelated device types. - Uses static storage: no allocated list nodes and no registry cleanup. - Does not require ordering between target constructors. ### Constraints - Constructors must only register metadata, not enumerate or initialize QOM classes. - Consumers must run after startup constructors have completed. - Each registration node must be inserted exactly once. - Registry order must not be treated as a meaningful target ordering. - This simple design assumes compiled-in targets; runtime loading or unloading would require additional lifecycle handling. ## Comparison | Aspect | QOM class cache | Static constructor registry | |---|---|---| | Discovery mechanism | QOM enumeration | Direct metadata registration | | Explicit startup initialization | Required | Not required | | Heap allocation for list nodes | Yes | No | | Cleanup policy | Required if releasing the cache | No registry cleanup | | Dependency on QOM initialization | Yes | No | | Registration-order sensitivity | Avoided through explicit sequencing | Avoided by consuming after constructors | | Late target registration | Cache needs updating | Requires a defined runtime registration policy | ## Recommendation Prefer the constructor-populated registry with statically allocated nodes. `TargetInfo` describes the binary's compiled-in capabilities. Accessing that metadata should not require initializing the device model or maintaining an allocated cache of QOM classes. The QOM cache fixes the immediate failure, but introduces an additional startup contract and ownership policy. A static constructor registry removes the underlying dependency and avoids heap allocation for the registry itself. -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-12 21:27 ` Yonggang Luo @ 2026-10-13 3:57 ` Pierrick Bouvier 2026-10-13 8:58 ` Yonggang Luo 0 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-13 3:57 UTC (permalink / raw) To: luoyonggang Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/12/26 2:27 PM, Yonggang Luo wrote: > On Thu, Oct 8, 2026 at 7:28 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> wrote: >> >> On 10/7/2026 4:02 PM, Yonggang Luo wrote: >>> On Thu, Oct 8, 2026 at 6:31 AM Pierrick Bouvier >>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>> >>>> On 10/7/2026 1:50 PM, Yonggang Luo wrote: >>>>> On Thu, Oct 8, 2026 at 4:29 AM Pierrick Bouvier >>>>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>>>> >>>>>> On 10/7/2026 4:48 AM, Yonggang Luo wrote: >>>>>>> Register target definitions through constructors instead of >>>>>>> MODULE_INIT_TARGET_INFO, making target_info_list() and target_info() >>>>>>> available on entry to main(), without explicit initialization or a >>>>>>> call to module_call_init(MODULE_INIT_QOM). >>>>>>> >>>>>>> Keep the target list sorted by target_arch and default to its first >>>>>>> entry. Provide an unknown TargetInfo fallback for target-independent >>>>>>> tools such as qemu-img and unit tests that link no target-info-def.c >>>>>>> objects. >>>>>>> >>>>>>> Remove the obsolete QOM target-info registration infrastructure and >>>>>>> update the multi-target test to inspect target information before >>>>>>> initializing QOM. >>>>>>> >>>>>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> >>>>>>> --- >>>>>>> include/qemu/module.h | 1 - >>>>>>> include/qemu/target-info-def.h | 56 +++++++++++++++++++++++++++--- >>>>>>> include/qemu/target-info-init.h | 53 ---------------------------- >>>>>>> include/qemu/target-info-qom.h | 31 ----------------- >>>>>>> include/qemu/target-info.h | 9 +++++ >>>>>>> meson.build | 6 ++-- >>>>>>> system/vl.c | 4 --- >>>>>>> target-info-def.c | 1 - >>>>>>> target-info-qom.c | 60 -------------------------------- >>>>>>> target-info.c | 61 ++++++++++++++++++++++++++++++++- >>>>>>> tests/qtest/fuzz/fuzz.c | 3 -- >>>>>>> tests/unit/test-multi-target.c | 12 +++---- >>>>>>> 12 files changed, 129 insertions(+), 168 deletions(-) >>>>>>> delete mode 100644 include/qemu/target-info-init.h >>>>>>> delete mode 100644 include/qemu/target-info-qom.h >>>>>>> delete mode 100644 target-info-qom.c >>>>>>> >>>>>> >>>>>> This approach (custom list based) was considered before implementing >>>>>> things with QOM Types. The rationale I followed was that if everything >>>>>> is in QOM, we might better follow that for consistency sake. >>>>>> Yes, the compromise if that we need an extra init step, but it was not a >>>>>> problem to add it. >>>>> I have issue to add the init step for unit-tests, and hard to write the -target >>>>> parse procedure and get it right. Not means this won't work. but for >>>>> me, too much >>>>> coupled. >>>>> >>>> >>>> We already have such a test upstream: >>>> https://gitlab.com/qemu-project/qemu/-/blob/master/tests/unit/test-multi-target.c#L35 >>>> >>>> The init sequence is quite straightforward: >>>> >>>> ``` >>>> /* initialize target types, and only them */ >>>> module_call_init(MODULE_INIT_TARGET_INFO); >>>> >>>> /* we can get the list if we want, for -target or any other purpose */ >>>> g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false); >>>> >>>> /* set the global target info from any element in this list */ >>>> TargetInfo* ti = ...; >>>> target_info_qom_set_target_info(ti); >>>> >>>> /* register rest of QOM types */ >>>> module_call_init(MODULE_INIT_QOM); >>>> ``` >>>> >>>> It works fine to implement -target (if we would like to do it), since I >>>> implemented it myself. That was also my initial motivation by the way. >>>> >>>> Also, I appreciate that target-info is NULL by default, it crashes >>>> loudly when it has not been set, and make it easy to find who depends on it. >>>> >>>>> If we treat target_info as a QOM, but QOM needs target_info to set >>>>> up(is_avaible). That makes >>>>> the init sequence too much of a burden. >>>>> >>>> >>>> See sequence above, the solution is to initialize TARGET_INFO first, >>>> before the rest of QOM. You end up with the same result than with a >>>> statically initialized list. >>>> >>>>> >>>>> is_available is depends on target_arch >>>>> And before this patch, target_arch depends on QOM, pulls user/softmmu because >>>>> target_info_init. By moving target-info to be a custom list based, we >>>>> can decouple >>>>> target-info from qom/softmmu/user. and target-info will always >>>>> available once "main(argv, argc)" is entered. We also have the >>>>> advantage of doing all sorts >>>>> of tests against it. >>>>> >>>> >>>> Which kind of tests are you trying to add? >>>> >>>> For now, the exact list of places where we need to do this initialize >>>> target dance are: >>>> - system/vl.c: module_call_init(MODULE_INIT_TARGET_INFO); >>>> - tests/qtest/fuzz/fuzz.c: module_call_init(MODULE_INIT_TARGET_INFO); >>>> - tests/unit/test-multi-target.c: >>> >>> # Multi targets test >>> if multi_target_objects != [] >>> test('test-multi-target', >>> executable('test-multi-target', >>> sources: [multi_target_crates, files('test-multi-target.c')], >>> dependencies: multi_target_deps, >>> objects: multi_target_objects, >>> link_depends: [block_syms, qemu_syms], >>> link_args: multi_target_link_args), >>> suite: ['unit']) >>> endif >>> >>> I see this test, I am trying to add tests that do not pull so many >>> multi_target_objects, as it would be huge. >> >> Agree, we should not add more binary. >> If you need truly multi targets test, this existing binary is a good >> place to start: just add a second test in it. >> >>> Just pull qom only. And I am trying to call target_info() in >>> object.c, as inspect machines with >>> qemu-system is rejected, so maybe that's not an issue anymore >>> >> >> Seems like a good candidate for the multi-target.c test. >> >>> >>> I means Subject: [PATCH v3 00/10] machine: uniquify virt QOM names >>> https://lore.kernel.org/qemu-devel/20260926081551.29-1-luoyonggang@gmail.com/#r >>> >>> So the current design always rejects types that do not belong to the >>> current target. Listing them >>> all is not an option at all. With this restriction, then these are >>> indeed not needed. >>> So I'll wait for your work first, otherwise it's always conflicting. >>> >>> >>>> module_call_init(MODULE_INIT_TARGET_INFO); >>>> >>>> If we want more tests, I'm totally ok to move this init code to >>>> target-info.c, and replace call sites if needed. >>>> >>>>> >>>>> Tools such as qemu-img and unit tests may link target-info.c without any >>>>> target-info-def.c objects. Their target list remains empty, so use this >>>>> fallback. >>>>> >>>> >>>> Why should this tool get access to target list? qemu-img deals with disk >>>> images, and is unrelated to targets. >>>> >>>>> >>>>> static TypeImpl *type_register_internal(const TypeInfo *info) >>>>> { >>>>> TypeImpl *ti; >>>>> >>>>> if (!type_name_is_valid(info->name)) { >>>>> fprintf(stderr, "Registering '%s' with illegal type name\n", >>>>> info->name); >>>>> abort(); >>>>> } >>>>> >>>>> if (info->is_available && !info->is_available()) { >>>>> return NULL; >>>>> } >>>>> >>>>> ti = type_new(info); >>>>> >>>>> type_table_add(ti); >>>>> return ti; >>>>> } >>>>> >>>>>> >>>>>> Is there another good value this list approach brings compared to what >>>>>> exists? >>>>>> >>>>>> Regards, >>>>>> Pierrick >>>>> >>>>> >>>>> >>>> >>> >>> >> > > > Hi, the cycle dependencies issue happened again, deal with it's a bit > nasty, there is workaround, but I think > the constructor list is the best, here is the rationale: > > > # Target discovery during QOM registration > > ## Problem > > Machine registration needs the list of targets compiled into the binary. > Currently, it obtains that list through: > > ```c > object_class_get_list(TYPE_TARGET_INFO, false); > ``` > > Despite the filter, QOM initializes every registered type before checking > whether it implements the requested type. > > During `MODULE_INIT_QOM`, registration is only partially complete. A device > may already be registered while its parent's registration callback has not > run, causing failures such as: > > ```text > Type 'sys-bus-device' is missing its parent 'device' > ``` > > The parent is linked into the binary. The problem is premature > initialization, not a missing library. > > ## Option 1: cache target-info QOM classes > > Enumerate target-info classes once, before device registration starts. > Machine registration then reads the cache instead of enumerating QOM. > > ### Demo > > Declare shared helpers: > > ```c > void target_info_qom_init(void); > const GSList *target_info_qom_get_targets(void); > ``` > > Implement the cache: > > ```c > static GSList *target_info_classes; > static bool target_info_initialized; > > void target_info_qom_init(void) > { > if (target_info_initialized) { > return; > } > > module_call_init(MODULE_INIT_TARGET_INFO); > target_info_classes = object_class_get_list(TYPE_TARGET_INFO, false); > target_info_initialized = true; > } > > const GSList *target_info_qom_get_targets(void) > { > assert(target_info_initialized); > return target_info_classes; > } > ``` > > Initialize it before other QOM registration: > > ```c > target_info_qom_init(); > module_call_init(MODULE_INIT_QOM); > ``` > > Machine registration uses the borrowed cache: > > ```c > for (const GSList *l = target_info_qom_get_targets(); l; l = l->next) { > const TargetInfo *ti = TARGET_INFO_CLASS(l->data)->target_info; > > machine_register_virt_type_for_target(info, name_suffix, arch_mask, > latest, ti); > } > ``` > > `target_info_qom_set_target()` should also use the cached list instead of > enumerating QOM again. > > ### Advantages > > - Preserves the existing QOM-based representation. > - Avoids enumeration during incomplete device registration. > - Requires relatively small changes. > > ### Disadvantages > > - Every relevant executable and test must initialize the cache before > starting QOM registration. > - `object_class_get_list()` allocates list nodes. > - Callers borrow the list, so it cannot be freed while they are using it. > - Cleanup is possible after all consumers finish, but requires an explicit > lifecycle policy. Keeping the cache until process exit is a lifetime > allocation, not inherently an unreachable memory leak. > - Target-info types registered after cache creation are not included. > - Target discovery remains coupled to QOM class initialization. > > ## Option 2: constructor-populated TargetInfo registry > > Each target registers its immutable `TargetInfo` pointer directly. > Machine registration later iterates the registry without querying QOM. > > Use a statically allocated node per target so registration requires no > heap allocation. > > ### Demo > > Define a registration node and accessors: > > ```c > typedef struct TargetInfoRegistration { > const TargetInfo *info; > struct TargetInfoRegistration *next; > } TargetInfoRegistration; > > void target_info_register(TargetInfoRegistration *entry); > const TargetInfoRegistration *target_info_get_targets(void); > ``` > > Implement the registry in shared code: > > ```c > static TargetInfoRegistration *target_info_targets; > > void target_info_register(TargetInfoRegistration *entry) > { > entry->next = target_info_targets; > target_info_targets = entry; > } > > const TargetInfoRegistration *target_info_get_targets(void) > { > return target_info_targets; > } > ``` > > Each target's translation unit provides its own static node and > constructor. For example: > > ```c > static TargetInfoRegistration target_info_registration = { > .info = &target_info_stub, > }; > > static void __attribute__((constructor)) register_target_info(void) > { > target_info_register(&target_info_registration); > } > ``` > > The constructor must run exactly once per node. The existing target-info > initialization macro can generate this registration code alongside the > QOM registration code; user-mode target-info behavior should remain > unchanged. > > Machine registration consumes the completed registry: > > ```c > for (const TargetInfoRegistration *entry = target_info_get_targets(); > entry; > entry = entry->next) { > machine_register_virt_type_for_target(info, name_suffix, arch_mask, > latest, entry->info); > } > ``` > > The sequence is: > > ```text > Target constructors register static metadata pointers > ↓ > Startup constructors finish > ↓ > Machine registration iterates the completed registry > ``` > > QOM target-info classes can remain available for introspection. > > ### Advantages > > - Makes target discovery independent of QOM initialization. > - Removes the explicit cache-initialization step from executables and tests. > - Avoids premature initialization of unrelated device types. > - Uses static storage: no allocated list nodes and no registry cleanup. > - Does not require ordering between target constructors. > > ### Constraints > > - Constructors must only register metadata, not enumerate or initialize > QOM classes. > - Consumers must run after startup constructors have completed. > - Each registration node must be inserted exactly once. > - Registry order must not be treated as a meaningful target ordering. > - This simple design assumes compiled-in targets; runtime loading or > unloading would require additional lifecycle handling. > > ## Comparison > > | Aspect | QOM class cache | Static constructor registry | > |---|---|---| > | Discovery mechanism | QOM enumeration | Direct metadata registration | > | Explicit startup initialization | Required | Not required | > | Heap allocation for list nodes | Yes | No | > | Cleanup policy | Required if releasing the cache | No registry cleanup | > | Dependency on QOM initialization | Yes | No | > | Registration-order sensitivity | Avoided through explicit sequencing > | Avoided by consuming after constructors | > | Late target registration | Cache needs updating | Requires a defined > runtime registration policy | > > ## Recommendation > > Prefer the constructor-populated registry with statically allocated nodes. > > `TargetInfo` describes the binary's compiled-in capabilities. Accessing > that metadata should not require initializing the device model or > maintaining an allocated cache of QOM classes. > > The QOM cache fixes the immediate failure, but introduces an additional > startup contract and ownership policy. A static constructor registry > removes the underlying dependency and avoids heap allocation for the > registry itself. > I will politely say one last time (and ignore this in the future): please do not copy paste AI summary to motivate any kind of design. Also, please do not post inline patches. In case you would like to develop an idea, send a minimal series (with one or two patches) presenting the concept and implementation, it's more efficient for collaboration. Regards, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 4/8] target-info: replace QOM registration with a constructor list 2026-10-13 3:57 ` Pierrick Bouvier @ 2026-10-13 8:58 ` Yonggang Luo 0 siblings, 0 replies; 62+ messages in thread From: Yonggang Luo @ 2026-10-13 8:58 UTC (permalink / raw) To: Pierrick Bouvier Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Tue, Oct 13, 2026 at 11:57 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/12/26 2:27 PM, Yonggang Luo wrote: > > On Thu, Oct 8, 2026 at 7:28 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> wrote: > >> > >> On 10/7/2026 4:02 PM, Yonggang Luo wrote: > >>> On Thu, Oct 8, 2026 at 6:31 AM Pierrick Bouvier > >>> <pierrick.bouvier@oss.qualcomm.com> wrote: > >>>> > >>>> On 10/7/2026 1:50 PM, Yonggang Luo wrote: > >>>>> On Thu, Oct 8, 2026 at 4:29 AM Pierrick Bouvier > >>>>> <pierrick.bouvier@oss.qualcomm.com> wrote: > >>>>>> > >>>>>> On 10/7/2026 4:48 AM, Yonggang Luo wrote: > >>>>>>> Register target definitions through constructors instead of > >>>>>>> MODULE_INIT_TARGET_INFO, making target_info_list() and target_info() > >>>>>>> available on entry to main(), without explicit initialization or a > >>>>>>> call to module_call_init(MODULE_INIT_QOM). > >>>>>>> > >>>>>>> Keep the target list sorted by target_arch and default to its first > >>>>>>> entry. Provide an unknown TargetInfo fallback for target-independent > >>>>>>> tools such as qemu-img and unit tests that link no target-info-def.c > >>>>>>> objects. > >>>>>>> > >>>>>>> Remove the obsolete QOM target-info registration infrastructure and > >>>>>>> update the multi-target test to inspect target information before > >>>>>>> initializing QOM. > >>>>>>> > >>>>>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > >>>>>>> --- > >>>>>>> include/qemu/module.h | 1 - > >>>>>>> include/qemu/target-info-def.h | 56 +++++++++++++++++++++++++++--- > >>>>>>> include/qemu/target-info-init.h | 53 ---------------------------- > >>>>>>> include/qemu/target-info-qom.h | 31 ----------------- > >>>>>>> include/qemu/target-info.h | 9 +++++ > >>>>>>> meson.build | 6 ++-- > >>>>>>> system/vl.c | 4 --- > >>>>>>> target-info-def.c | 1 - > >>>>>>> target-info-qom.c | 60 -------------------------------- > >>>>>>> target-info.c | 61 ++++++++++++++++++++++++++++++++- > >>>>>>> tests/qtest/fuzz/fuzz.c | 3 -- > >>>>>>> tests/unit/test-multi-target.c | 12 +++---- > >>>>>>> 12 files changed, 129 insertions(+), 168 deletions(-) > >>>>>>> delete mode 100644 include/qemu/target-info-init.h > >>>>>>> delete mode 100644 include/qemu/target-info-qom.h > >>>>>>> delete mode 100644 target-info-qom.c > >>>>>>> > >>>>>> > >>>>>> This approach (custom list based) was considered before implementing > >>>>>> things with QOM Types. The rationale I followed was that if everything > >>>>>> is in QOM, we might better follow that for consistency sake. > >>>>>> Yes, the compromise if that we need an extra init step, but it was not a > >>>>>> problem to add it. > >>>>> I have issue to add the init step for unit-tests, and hard to write the -target > >>>>> parse procedure and get it right. Not means this won't work. but for > >>>>> me, too much > >>>>> coupled. > >>>>> > >>>> > >>>> We already have such a test upstream: > >>>> https://gitlab.com/qemu-project/qemu/-/blob/master/tests/unit/test-multi-target.c#L35 > >>>> > >>>> The init sequence is quite straightforward: > >>>> > >>>> ``` > >>>> /* initialize target types, and only them */ > >>>> module_call_init(MODULE_INIT_TARGET_INFO); > >>>> > >>>> /* we can get the list if we want, for -target or any other purpose */ > >>>> g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false); > >>>> > >>>> /* set the global target info from any element in this list */ > >>>> TargetInfo* ti = ...; > >>>> target_info_qom_set_target_info(ti); > >>>> > >>>> /* register rest of QOM types */ > >>>> module_call_init(MODULE_INIT_QOM); > >>>> ``` > >>>> > >>>> It works fine to implement -target (if we would like to do it), since I > >>>> implemented it myself. That was also my initial motivation by the way. > >>>> > >>>> Also, I appreciate that target-info is NULL by default, it crashes > >>>> loudly when it has not been set, and make it easy to find who depends on it. > >>>> > >>>>> If we treat target_info as a QOM, but QOM needs target_info to set > >>>>> up(is_avaible). That makes > >>>>> the init sequence too much of a burden. > >>>>> > >>>> > >>>> See sequence above, the solution is to initialize TARGET_INFO first, > >>>> before the rest of QOM. You end up with the same result than with a > >>>> statically initialized list. > >>>> > >>>>> > >>>>> is_available is depends on target_arch > >>>>> And before this patch, target_arch depends on QOM, pulls user/softmmu because > >>>>> target_info_init. By moving target-info to be a custom list based, we > >>>>> can decouple > >>>>> target-info from qom/softmmu/user. and target-info will always > >>>>> available once "main(argv, argc)" is entered. We also have the > >>>>> advantage of doing all sorts > >>>>> of tests against it. > >>>>> > >>>> > >>>> Which kind of tests are you trying to add? > >>>> > >>>> For now, the exact list of places where we need to do this initialize > >>>> target dance are: > >>>> - system/vl.c: module_call_init(MODULE_INIT_TARGET_INFO); > >>>> - tests/qtest/fuzz/fuzz.c: module_call_init(MODULE_INIT_TARGET_INFO); > >>>> - tests/unit/test-multi-target.c: > >>> > >>> # Multi targets test > >>> if multi_target_objects != [] > >>> test('test-multi-target', > >>> executable('test-multi-target', > >>> sources: [multi_target_crates, files('test-multi-target.c')], > >>> dependencies: multi_target_deps, > >>> objects: multi_target_objects, > >>> link_depends: [block_syms, qemu_syms], > >>> link_args: multi_target_link_args), > >>> suite: ['unit']) > >>> endif > >>> > >>> I see this test, I am trying to add tests that do not pull so many > >>> multi_target_objects, as it would be huge. > >> > >> Agree, we should not add more binary. > >> If you need truly multi targets test, this existing binary is a good > >> place to start: just add a second test in it. > >> > >>> Just pull qom only. And I am trying to call target_info() in > >>> object.c, as inspect machines with > >>> qemu-system is rejected, so maybe that's not an issue anymore > >>> > >> > >> Seems like a good candidate for the multi-target.c test. > >> > >>> > >>> I means Subject: [PATCH v3 00/10] machine: uniquify virt QOM names > >>> https://lore.kernel.org/qemu-devel/20260926081551.29-1-luoyonggang@gmail.com/#r > >>> > >>> So the current design always rejects types that do not belong to the > >>> current target. Listing them > >>> all is not an option at all. With this restriction, then these are > >>> indeed not needed. > >>> So I'll wait for your work first, otherwise it's always conflicting. > >>> > >>> > >>>> module_call_init(MODULE_INIT_TARGET_INFO); > >>>> > >>>> If we want more tests, I'm totally ok to move this init code to > >>>> target-info.c, and replace call sites if needed. > >>>> > >>>>> > >>>>> Tools such as qemu-img and unit tests may link target-info.c without any > >>>>> target-info-def.c objects. Their target list remains empty, so use this > >>>>> fallback. > >>>>> > >>>> > >>>> Why should this tool get access to target list? qemu-img deals with disk > >>>> images, and is unrelated to targets. > >>>> > >>>>> > >>>>> static TypeImpl *type_register_internal(const TypeInfo *info) > >>>>> { > >>>>> TypeImpl *ti; > >>>>> > >>>>> if (!type_name_is_valid(info->name)) { > >>>>> fprintf(stderr, "Registering '%s' with illegal type name\n", > >>>>> info->name); > >>>>> abort(); > >>>>> } > >>>>> > >>>>> if (info->is_available && !info->is_available()) { > >>>>> return NULL; > >>>>> } > >>>>> > >>>>> ti = type_new(info); > >>>>> > >>>>> type_table_add(ti); > >>>>> return ti; > >>>>> } > >>>>> > >>>>>> > >>>>>> Is there another good value this list approach brings compared to what > >>>>>> exists? > >>>>>> > >>>>>> Regards, > >>>>>> Pierrick > >>>>> > >>>>> > >>>>> > >>>> > >>> > >>> > >> > > > > > > Hi, the cycle dependencies issue happened again, deal with it's a bit > > nasty, there is workaround, but I think > > the constructor list is the best, here is the rationale: > > > > > > # Target discovery during QOM registration > > > > ## Problem > > > > Machine registration needs the list of targets compiled into the binary. > > Currently, it obtains that list through: > > > > ```c > > object_class_get_list(TYPE_TARGET_INFO, false); > > ``` > > > > Despite the filter, QOM initializes every registered type before checking > > whether it implements the requested type. > > > > During `MODULE_INIT_QOM`, registration is only partially complete. A device > > may already be registered while its parent's registration callback has not > > run, causing failures such as: > > > > ```text > > Type 'sys-bus-device' is missing its parent 'device' > > ``` > > > > The parent is linked into the binary. The problem is premature > > initialization, not a missing library. > > > > ## Option 1: cache target-info QOM classes > > > > Enumerate target-info classes once, before device registration starts. > > Machine registration then reads the cache instead of enumerating QOM. > > > > ### Demo > > > > Declare shared helpers: > > > > ```c > > void target_info_qom_init(void); > > const GSList *target_info_qom_get_targets(void); > > ``` > > > > Implement the cache: > > > > ```c > > static GSList *target_info_classes; > > static bool target_info_initialized; > > > > void target_info_qom_init(void) > > { > > if (target_info_initialized) { > > return; > > } > > > > module_call_init(MODULE_INIT_TARGET_INFO); > > target_info_classes = object_class_get_list(TYPE_TARGET_INFO, false); > > target_info_initialized = true; > > } > > > > const GSList *target_info_qom_get_targets(void) > > { > > assert(target_info_initialized); > > return target_info_classes; > > } > > ``` > > > > Initialize it before other QOM registration: > > > > ```c > > target_info_qom_init(); > > module_call_init(MODULE_INIT_QOM); > > ``` > > > > Machine registration uses the borrowed cache: > > > > ```c > > for (const GSList *l = target_info_qom_get_targets(); l; l = l->next) { > > const TargetInfo *ti = TARGET_INFO_CLASS(l->data)->target_info; > > > > machine_register_virt_type_for_target(info, name_suffix, arch_mask, > > latest, ti); > > } > > ``` > > > > `target_info_qom_set_target()` should also use the cached list instead of > > enumerating QOM again. > > > > ### Advantages > > > > - Preserves the existing QOM-based representation. > > - Avoids enumeration during incomplete device registration. > > - Requires relatively small changes. > > > > ### Disadvantages > > > > - Every relevant executable and test must initialize the cache before > > starting QOM registration. > > - `object_class_get_list()` allocates list nodes. > > - Callers borrow the list, so it cannot be freed while they are using it. > > - Cleanup is possible after all consumers finish, but requires an explicit > > lifecycle policy. Keeping the cache until process exit is a lifetime > > allocation, not inherently an unreachable memory leak. > > - Target-info types registered after cache creation are not included. > > - Target discovery remains coupled to QOM class initialization. > > > > ## Option 2: constructor-populated TargetInfo registry > > > > Each target registers its immutable `TargetInfo` pointer directly. > > Machine registration later iterates the registry without querying QOM. > > > > Use a statically allocated node per target so registration requires no > > heap allocation. > > > > ### Demo > > > > Define a registration node and accessors: > > > > ```c > > typedef struct TargetInfoRegistration { > > const TargetInfo *info; > > struct TargetInfoRegistration *next; > > } TargetInfoRegistration; > > > > void target_info_register(TargetInfoRegistration *entry); > > const TargetInfoRegistration *target_info_get_targets(void); > > ``` > > > > Implement the registry in shared code: > > > > ```c > > static TargetInfoRegistration *target_info_targets; > > > > void target_info_register(TargetInfoRegistration *entry) > > { > > entry->next = target_info_targets; > > target_info_targets = entry; > > } > > > > const TargetInfoRegistration *target_info_get_targets(void) > > { > > return target_info_targets; > > } > > ``` > > > > Each target's translation unit provides its own static node and > > constructor. For example: > > > > ```c > > static TargetInfoRegistration target_info_registration = { > > .info = &target_info_stub, > > }; > > > > static void __attribute__((constructor)) register_target_info(void) > > { > > target_info_register(&target_info_registration); > > } > > ``` > > > > The constructor must run exactly once per node. The existing target-info > > initialization macro can generate this registration code alongside the > > QOM registration code; user-mode target-info behavior should remain > > unchanged. > > > > Machine registration consumes the completed registry: > > > > ```c > > for (const TargetInfoRegistration *entry = target_info_get_targets(); > > entry; > > entry = entry->next) { > > machine_register_virt_type_for_target(info, name_suffix, arch_mask, > > latest, entry->info); > > } > > ``` > > > > The sequence is: > > > > ```text > > Target constructors register static metadata pointers > > ↓ > > Startup constructors finish > > ↓ > > Machine registration iterates the completed registry > > ``` > > > > QOM target-info classes can remain available for introspection. > > > > ### Advantages > > > > - Makes target discovery independent of QOM initialization. > > - Removes the explicit cache-initialization step from executables and tests. > > - Avoids premature initialization of unrelated device types. > > - Uses static storage: no allocated list nodes and no registry cleanup. > > - Does not require ordering between target constructors. > > > > ### Constraints > > > > - Constructors must only register metadata, not enumerate or initialize > > QOM classes. > > - Consumers must run after startup constructors have completed. > > - Each registration node must be inserted exactly once. > > - Registry order must not be treated as a meaningful target ordering. > > - This simple design assumes compiled-in targets; runtime loading or > > unloading would require additional lifecycle handling. > > > > ## Comparison > > > > | Aspect | QOM class cache | Static constructor registry | > > |---|---|---| > > | Discovery mechanism | QOM enumeration | Direct metadata registration | > > | Explicit startup initialization | Required | Not required | > > | Heap allocation for list nodes | Yes | No | > > | Cleanup policy | Required if releasing the cache | No registry cleanup | > > | Dependency on QOM initialization | Yes | No | > > | Registration-order sensitivity | Avoided through explicit sequencing > > | Avoided by consuming after constructors | > > | Late target registration | Cache needs updating | Requires a defined > > runtime registration policy | > > > > ## Recommendation > > > > Prefer the constructor-populated registry with statically allocated nodes. > > > > `TargetInfo` describes the binary's compiled-in capabilities. Accessing > > that metadata should not require initializing the device model or > > maintaining an allocated cache of QOM classes. > > > > The QOM cache fixes the immediate failure, but introduces an additional > > startup contract and ownership policy. A static constructor registry > > removes the underlying dependency and avoids heap allocation for the > > registry itself. > > > > I will politely say one last time (and ignore this in the future): apologize, I am doing this mainly because my poor English, I am post a small patches instead. > please do not copy paste AI summary to motivate any kind of design. > Also, please do not post inline patches. In case you would like to > develop an idea, send a minimal series (with one or two patches) > presenting the concept and implementation, it's more efficient for > collaboration. > > Regards, > Pierrick -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 5/8] tests/unit: add target-info coverage for multi-target builds 2026-10-07 11:47 [PATCH 0/8] qom: pass TargetInfo to the is_available callback Yonggang Luo ` (3 preceding siblings ...) 2026-10-07 11:48 ` [PATCH 4/8] target-info: replace QOM registration with a constructor list Yonggang Luo @ 2026-10-07 11:48 ` Yonggang Luo 2026-10-07 11:48 ` [PATCH 6/8] meson: load all target .mak files into target_mak_all Yonggang Luo ` (4 subsequent siblings) 9 siblings, 0 replies; 62+ messages in thread From: Yonggang Luo @ 2026-10-07 11:48 UTC (permalink / raw) To: qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, Pierrick Bouvier, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny Link target-info-def.c objects from supported multi-target libraries into test-target-info. Verify target_info() is non-NULL and that target_info_list() contains one entry for each linked target. Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> --- MAINTAINERS | 1 + meson.build | 5 ++++- tests/unit/meson.build | 4 ++++ tests/unit/test-target-info.c | 38 +++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 tests/unit/test-target-info.c diff --git a/MAINTAINERS b/MAINTAINERS index cfe39dc2883..418c4e472a9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2149,6 +2149,7 @@ S: Supported F: include/qemu/target-info*.h F: target-info*.c F: tests/unit/test-multi-targets.c +F: tests/unit/test-target-info.c Xtensa Machines --------------- diff --git a/meson.build b/meson.build index 4097784e7a2..fd7a4f68389 100644 --- a/meson.build +++ b/meson.build @@ -4259,6 +4259,7 @@ endif traceable = [] multi_target_libs = [] multi_target_deps = [] +multi_target_target_info_objects = [] multi_target_crates = [] multi_target_supported_targets = [ 'aarch64-softmmu', @@ -4274,6 +4275,7 @@ multi_target_supported_targets = [ ] emulators = {} +target_info_def = files('target-info-def.c') foreach target : target_dirs config_target = config_target_mak[target] target_name = config_target['TARGET_NAME'] @@ -4345,7 +4347,7 @@ foreach target : target_dirs endif endif - arch_srcs += files('target-info-def.c') + arch_srcs += target_info_def if target_base_arch in target_arch t = target_arch[target_base_arch].apply(config_target, strict: false) @@ -4428,6 +4430,7 @@ foreach target : target_dirs multi_target_libs += lib multi_target_deps += arch_deps multi_target_deps += target_stubs + multi_target_target_info_objects += lib.extract_objects(target_info_def) multi_target_crates += main_rs endif execs = [{ diff --git a/tests/unit/meson.build b/tests/unit/meson.build index d17435c1877..b2e8be24b05 100644 --- a/tests/unit/meson.build +++ b/tests/unit/meson.build @@ -43,6 +43,10 @@ tests = { 'test-qgraph': ['../qtest/libqos/qgraph.c'], 'check-qom-interface': [qom], 'check-qom-proplist': [qom], + 'test-target-info': [qom, declare_dependency( + objects: multi_target_target_info_objects, + compile_args: ['-DTARGET_INFO_DEF_COUNT=@0@'.format( + multi_target_target_info_objects.length())])], 'test-qemu-opts': [], 'test-keyval': [testqapi], 'test-logging': [], diff --git a/tests/unit/test-target-info.c b/tests/unit/test-target-info.c new file mode 100644 index 00000000000..e6de9b259e8 --- /dev/null +++ b/tests/unit/test-target-info.c @@ -0,0 +1,38 @@ +/* + * TargetInfo unit tests + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/target-info.h" +#include "qemu/target-info-def.h" + +static int target_info_list_count(void) +{ + TargetInfoNode *node; + int n = 0; + + QLIST_FOREACH(node, target_info_list(), next) { + n++; + } + return n; +} + +static void test_target_info_not_null(void) +{ + g_assert_nonnull(target_info()); +} + +static void test_target_info_list_count(void) +{ + g_assert_cmpint(target_info_list_count(), ==, TARGET_INFO_DEF_COUNT); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + g_test_add_func("/target-info/not-null", test_target_info_not_null); + g_test_add_func("/target-info/list-count", test_target_info_list_count); + return g_test_run(); +} -- 2.55.0.windows.3 ^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 6/8] meson: load all target .mak files into target_mak_all 2026-10-07 11:47 [PATCH 0/8] qom: pass TargetInfo to the is_available callback Yonggang Luo ` (4 preceding siblings ...) 2026-10-07 11:48 ` [PATCH 5/8] tests/unit: add target-info coverage for multi-target builds Yonggang Luo @ 2026-10-07 11:48 ` Yonggang Luo 2026-10-07 20:30 ` Pierrick Bouvier 2026-10-07 11:48 ` [PATCH 7/8] target-info: Replace handwritten architecture checks with generated code Yonggang Luo ` (3 subsequent siblings) 9 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-07 11:48 UTC (permalink / raw) To: qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, Pierrick Bouvier, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny Load every configs/targets/*.mak once into target_mak_all, keyed by target_dirs_all, with TARGET_BASE_ARCH defaulted to TARGET_ARCH. The per-target loop now takes its config from target_mak_all instead of loading the file again. target_dirs is still the --target-list filtered subset and is the only list built. target_mak_all is for later use by code that needs target properties independent of --target-list, such as generating TargetInfo helpers for every target. Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> --- meson.build | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index fd7a4f68389..d070dafe2a9 100644 --- a/meson.build +++ b/meson.build @@ -3239,6 +3239,21 @@ config_target_mak = {} config_base_arch_mak = {} config_target_info = {} +# Load every configs/targets/*.mak unconditionally; target_dirs is the +# --target-list filtered subset of target_dirs_all. +target_dirs_all = run_command(python, '-c', + 'import os, sys; print(" ".join(sorted(f[:-4] for f in os.listdir(sys.argv[1]) if f.endswith(".mak"))))', + meson.current_source_dir() / 'configs/targets', + check: true).stdout().split() +target_mak_all = {} +foreach target : target_dirs_all + mak = keyval.load('configs/targets' / target + '.mak') + if 'TARGET_BASE_ARCH' not in mak + mak += {'TARGET_BASE_ARCH': mak['TARGET_ARCH']} + endif + target_mak_all += {target: mak} +endforeach + disassemblers = { 'alpha' : ['CONFIG_ALPHA_DIS'], 'avr' : ['CONFIG_AVR_DIS'], @@ -3318,7 +3333,7 @@ foreach target : target_dirs } endif - config_target += keyval.load('configs/targets' / target + '.mak') + config_target += target_mak_all[target] target_kconfig = [] foreach sym: accelerators @@ -3348,9 +3363,6 @@ foreach target : target_dirs # Add default keys config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } - if 'TARGET_BASE_ARCH' not in config_target - config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} - endif if 'TARGET_ABI_DIR' not in config_target config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']} endif -- 2.55.0.windows.3 ^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [PATCH 6/8] meson: load all target .mak files into target_mak_all 2026-10-07 11:48 ` [PATCH 6/8] meson: load all target .mak files into target_mak_all Yonggang Luo @ 2026-10-07 20:30 ` Pierrick Bouvier 0 siblings, 0 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-07 20:30 UTC (permalink / raw) To: Yonggang Luo, qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/7/2026 4:48 AM, Yonggang Luo wrote: > Load every configs/targets/*.mak once into target_mak_all, keyed by > target_dirs_all, with TARGET_BASE_ARCH defaulted to TARGET_ARCH. The > per-target loop now takes its config from target_mak_all instead of > loading the file again. > > target_dirs is still the --target-list filtered subset and is the only > list built. target_mak_all is for later use by code that needs target > properties independent of --target-list, such as generating > TargetInfo helpers for every target. > > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > --- > meson.build | 20 ++++++++++++++++---- > 1 file changed, 16 insertions(+), 4 deletions(-) > > diff --git a/meson.build b/meson.build > index fd7a4f68389..d070dafe2a9 100644 > --- a/meson.build > +++ b/meson.build > @@ -3239,6 +3239,21 @@ config_target_mak = {} > config_base_arch_mak = {} > config_target_info = {} > > +# Load every configs/targets/*.mak unconditionally; target_dirs is the > +# --target-list filtered subset of target_dirs_all. > +target_dirs_all = run_command(python, '-c', > + 'import os, sys; print(" ".join(sorted(f[:-4] for f in os.listdir(sys.argv[1]) if f.endswith(".mak"))))', > + meson.current_source_dir() / 'configs/targets', > + check: true).stdout().split() > +target_mak_all = {} > +foreach target : target_dirs_all > + mak = keyval.load('configs/targets' / target + '.mak') > + if 'TARGET_BASE_ARCH' not in mak > + mak += {'TARGET_BASE_ARCH': mak['TARGET_ARCH']} > + endif > + target_mak_all += {target: mak} > +endforeach > + > disassemblers = { > 'alpha' : ['CONFIG_ALPHA_DIS'], > 'avr' : ['CONFIG_AVR_DIS'], > @@ -3318,7 +3333,7 @@ foreach target : target_dirs > } > endif > > - config_target += keyval.load('configs/targets' / target + '.mak') > + config_target += target_mak_all[target] > > target_kconfig = [] > foreach sym: accelerators > @@ -3348,9 +3363,6 @@ foreach target : target_dirs > > # Add default keys > config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } > - if 'TARGET_BASE_ARCH' not in config_target > - config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} > - endif > if 'TARGET_ABI_DIR' not in config_target > config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']} > endif What is the goal of this patch? In case it's to simplify further patches, if a script can read one .mak files, it can probably read several also. Regards, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 7/8] target-info: Replace handwritten architecture checks with generated code 2026-10-07 11:47 [PATCH 0/8] qom: pass TargetInfo to the is_available callback Yonggang Luo ` (5 preceding siblings ...) 2026-10-07 11:48 ` [PATCH 6/8] meson: load all target .mak files into target_mak_all Yonggang Luo @ 2026-10-07 11:48 ` Yonggang Luo 2026-10-07 20:36 ` Pierrick Bouvier 2026-10-07 11:48 ` [PATCH 8/8] qom: pass TargetInfo to is_available for later use Yonggang Luo ` (2 subsequent siblings) 9 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-07 11:48 UTC (permalink / raw) To: qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, Pierrick Bouvier, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny Add scripts/gen-target-info.py to generate declarations and definitions for exact-target and base-family architecture checks from system target names and their TARGET_BASE_ARCH values. Provide target_is_<arch>() and target_is_base_<family>() checks for an explicit TargetInfo. Retain target_<arch>() and target_base_<family>() as wrappers using the current target. Wire the generator into Meson using all system target definitions so the available checks do not depend on --target-list. Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> --- include/qemu/target-info.h | 76 ++++------------------------- meson.build | 16 ++++++ scripts/gen-target-info.py | 99 ++++++++++++++++++++++++++++++++++++++ target-info.c | 62 +----------------------- 4 files changed, 125 insertions(+), 128 deletions(-) create mode 100644 scripts/gen-target-info.py diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h index d1928cecf84..88aa80e918c 100644 --- a/include/qemu/target-info.h +++ b/include/qemu/target-info.h @@ -51,74 +51,16 @@ const char *target_cpu_type(void); */ bool target_big_endian(void); -/** - * target_base_arm: - * - * Returns whether the target architecture is ARM or Aarch64. - */ -bool target_base_arm(void); - -/** - * target_arm: - * - * Returns whether the target architecture is ARM (32-bit, not Aarch64). - */ -bool target_arm(void); - -/** - * target_aarch64: - * - * Returns whether the target architecture is Aarch64. - */ -bool target_aarch64(void); - -/** - * target_m68k: - * - * Returns whether the target architecture is M68K. - */ -bool target_m68k(void); - -/** - * target_or1k: - * - * Returns whether the target architecture is OpenRISC 1000. - */ -bool target_or1k(void); - -/** - * target_base_ppc: - * - * Returns whether the target architecture is PowerPC 32-bit or 64-bit. - */ -bool target_base_ppc(void); - -/** - * target_ppc: - * - * Returns whether the target architecture is PowerPC 32-bit. - */ -bool target_ppc(void); - -/** - * target_ppc64: - * - * Returns whether the target architecture is PowerPC 64-bit. - */ -bool target_ppc64(void); - -/** - * target_s390x: - * - * Returns whether the target architecture is S390x. - */ -bool target_s390x(void); - -/** - * target_riscv64: +/* + * Exact-target and base-family helpers, generated by + * scripts/gen-target-info.py from the TARGET_BASE_ARCH of every + * system target: * - * Returns whether the target architecture is riscv64 + * bool target_is_<arch>(const TargetInfo *ti); + * bool target_<arch>(void); + * bool target_is_base_<family>(const TargetInfo *ti); + * bool target_base_<family>(void); */ -bool target_riscv64(void); +#include "target-info-gen.h" #endif diff --git a/meson.build b/meson.build index d070dafe2a9..8799b3f6d51 100644 --- a/meson.build +++ b/meson.build @@ -3581,6 +3581,22 @@ foreach d : hx_headers endforeach genh += hxdep +# Use target_mak_all, not target_dirs, so the generated helpers do not +# depend on --target-list. +target_info_gen_args = [] +foreach target, mak : target_mak_all + if target.endswith('-softmmu') + target_info_gen_args += ['--target', + target.split('-')[0] + '=' + mak['TARGET_BASE_ARCH']] + endif +endforeach +target_info_gen = custom_target('target-info-gen', + output: ['target-info-gen.h', 'target-info-gen.c.inc'], + depend_files: files('scripts/qapi/common.py'), + command: [python, files('scripts/gen-target-info.py'), + target_info_gen_args, '@OUTDIR@']) +genh += target_info_gen + ############### # Trace files # ############### diff --git a/scripts/gen-target-info.py b/scripts/gen-target-info.py new file mode 100644 index 00000000000..a4c3474140f --- /dev/null +++ b/scripts/gen-target-info.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +"""Generate TargetInfo target helpers and abstract machine parents. + +meson passes every system target with its TARGET_BASE_ARCH, independent +of --target-list, as --target <name>=<base>. <name> is a SysEmuTarget +member; a target without one fails to compile. + +For every target <arch> and every base family <family>: + bool target_is_<arch>(const TargetInfo *ti); + bool target_<arch>(void); + bool target_is_base_<family>(const TargetInfo *ti); + bool target_base_<family>(void); + TYPE_TARGET_<ARCH>_MACHINE "target-<arch>-machine" + TYPE_TARGET_BASE_<FAMILY>_MACHINE "target-base-<family>-machine" + +Machine parents are abstract and only registered when available. +<arch> parents inherit their <family> parent, which inherits TYPE_MACHINE. +""" + +import argparse +import os +import re +import sys +from typing import Dict, List + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from qapi.common import c_enum_const, c_name + +HEADER = "/* Generated by scripts/gen-target-info.py. Do not edit. */" +C_IDENT = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$") + + +def parse_targets(pairs: List[str]) -> Dict[str, List[str]]: + """Return {family: [target, ...]}, both sorted.""" + seen = set() + families: Dict[str, List[str]] = {} + for pair in pairs: + name, _, family = pair.partition("=") + if not name or not C_IDENT.match(family) or name in seen: + sys.exit(f"{sys.argv[0]}: bad or duplicate --target '{pair}'") + seen.add(name) + families.setdefault(family, []).append(name) + return {f: sorted(t) for f, t in sorted(families.items())} + + +def write(path: str, lines: List[str]) -> None: + with open(path, "w", encoding="utf-8", newline="\n") as fh: + fh.write("\n".join([HEADER, ""] + lines + [""])) + + +def predicate(fn: str, cases: List[str]) -> List[str]: + body = ([" switch (ti->target_arch) {"] + + [f" case {c}:" for c in cases] + + [" return true;", " default:", + " return false;", " }"]) + return [f"bool target_is_{fn}(const TargetInfo *ti)", "{", *body, "}", + "", f"bool target_{fn}(void)", "{", + f" return target_is_{fn}(target_info());", "}", ""] + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__.split("\n")[0]) + parser.add_argument("--target", action="append", required=True, + metavar="NAME=TARGET_BASE_ARCH") + parser.add_argument("outdir") + args = parser.parse_args() + families = parse_targets(args.target) + + # (helper suffix, QOM name, enum constants, parent macro or None) + entries = [] + for family, targets in families.items(): + consts = [c_enum_const("SysEmuTarget", t) for t in targets] + entries.append((f"base_{family}", f"target-base-{family}", + consts, None)) + for family, targets in families.items(): + for t in targets: + entries.append((c_name(t, False), f"target-{t}", + [c_enum_const("SysEmuTarget", t)], + f"TYPE_TARGET_BASE_{family.upper()}_MACHINE")) + + def macro(fn: str) -> str: + return f"TYPE_TARGET_{fn.upper()}_MACHINE" + + header = ["#ifndef TARGET_INFO_GEN_H", "#define TARGET_INFO_GEN_H", "", + "typedef struct TargetInfo TargetInfo;", ""] + for fn, _, _, _ in entries: + header += [f"bool target_is_{fn}(const TargetInfo *ti);", + f"bool target_{fn}(void);", ""] + write(os.path.join(args.outdir, "target-info-gen.h"), + header + ["#endif"]) + + source = [] + for fn, _, consts, _ in entries: + source += predicate(fn, consts) + write(os.path.join(args.outdir, "target-info-gen.c.inc"), source) + +if __name__ == "__main__": + main() diff --git a/target-info.c b/target-info.c index 8ccb333e365..fec8ee7c08e 100644 --- a/target-info.c +++ b/target-info.c @@ -101,64 +101,4 @@ bool target_big_endian(void) return target_endian_mode() == ENDIAN_MODE_BIG; } -bool target_base_arm(void) -{ - switch (target_arch()) { - case SYS_EMU_TARGET_ARM: - case SYS_EMU_TARGET_AARCH64: - return true; - default: - return false; - } -} - -bool target_arm(void) -{ - return target_arch() == SYS_EMU_TARGET_ARM; -} - -bool target_aarch64(void) -{ - return target_arch() == SYS_EMU_TARGET_AARCH64; -} - -bool target_m68k(void) -{ - return target_arch() == SYS_EMU_TARGET_M68K; -} - -bool target_or1k(void) -{ - return target_arch() == SYS_EMU_TARGET_OR1K; -} - -bool target_base_ppc(void) -{ - switch (target_arch()) { - case SYS_EMU_TARGET_PPC: - case SYS_EMU_TARGET_PPC64: - return true; - default: - return false; - } -} - -bool target_ppc(void) -{ - return target_arch() == SYS_EMU_TARGET_PPC; -} - -bool target_ppc64(void) -{ - return target_arch() == SYS_EMU_TARGET_PPC64; -} - -bool target_s390x(void) -{ - return target_arch() == SYS_EMU_TARGET_S390X; -} - -bool target_riscv64(void) -{ - return target_arch() == SYS_EMU_TARGET_RISCV64; -} +#include "target-info-gen.c.inc" -- 2.55.0.windows.3 ^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [PATCH 7/8] target-info: Replace handwritten architecture checks with generated code 2026-10-07 11:48 ` [PATCH 7/8] target-info: Replace handwritten architecture checks with generated code Yonggang Luo @ 2026-10-07 20:36 ` Pierrick Bouvier 0 siblings, 0 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-07 20:36 UTC (permalink / raw) To: Yonggang Luo, qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/7/2026 4:48 AM, Yonggang Luo wrote: > Add scripts/gen-target-info.py to generate declarations and definitions > for exact-target and base-family architecture checks from system target > names and their TARGET_BASE_ARCH values. > > Provide target_is_<arch>() and target_is_base_<family>() checks for an > explicit TargetInfo. Retain target_<arch>() and target_base_<family>() > as wrappers using the current target. > > Wire the generator into Meson using all system target definitions so > the available checks do not depend on --target-list. > > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > --- > include/qemu/target-info.h | 76 ++++------------------------- > meson.build | 16 ++++++ > scripts/gen-target-info.py | 99 ++++++++++++++++++++++++++++++++++++++ > target-info.c | 62 +----------------------- > 4 files changed, 125 insertions(+), 128 deletions(-) > create mode 100644 scripts/gen-target-info.py > If I had to pick between simple and manual boilerplate, and a python script generating C code, I would tend to choose the former. In this case, the set of targets is bounded, so manual code is really the way to go for me. If the repetition is really unbearable, macros are a way to deal with this. However, note that we will not need all the target_X to be defined, so I would prefer to not see any new variant added as long as it's not used. Regards, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-07 11:47 [PATCH 0/8] qom: pass TargetInfo to the is_available callback Yonggang Luo ` (6 preceding siblings ...) 2026-10-07 11:48 ` [PATCH 7/8] target-info: Replace handwritten architecture checks with generated code Yonggang Luo @ 2026-10-07 11:48 ` Yonggang Luo 2026-10-07 20:44 ` Pierrick Bouvier 2026-10-07 20:25 ` [PATCH 0/8] qom: pass TargetInfo to the is_available callback Pierrick Bouvier 2026-10-07 20:46 ` Pierrick Bouvier 9 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-07 11:48 UTC (permalink / raw) To: qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, Pierrick Bouvier, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny Change TypeInfo.is_available to the new TypeIsAvailable type, which takes a const TargetInfo *. Registration passes target_info(), so behavior is unchanged. object.h only forward-declares TargetInfo. Switch the existing users (raspi, raspi4b, ast27x0 evb and fc) and the generated machine parents to the matching target_is_<arch> helpers. Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> --- hw/arm/aspeed_ast27x0-fc.c | 2 +- hw/arm/aspeed_ast27x0_evb.c | 4 ++-- hw/arm/raspi.c | 4 ++-- hw/arm/raspi4b.c | 2 +- hw/arm/virt.c | 4 ++-- hw/m68k/virt.c | 4 ++-- hw/or1k/virt.c | 2 +- include/qom/object.h | 12 +++++++++++- qom/object.c | 3 ++- 9 files changed, 24 insertions(+), 13 deletions(-) diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c index 73362b60d2a..8a7c6a116ac 100644 --- a/hw/arm/aspeed_ast27x0-fc.c +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -234,7 +234,7 @@ static const TypeInfo ast2700fc_types[] = { .parent = TYPE_MACHINE, .class_init = ast2700fc_class_init, .instance_size = sizeof(Ast2700FCState), - .is_available = target_aarch64, + .is_available = target_is_aarch64, }, }; diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c index 460c9ff0d2e..02a8cff1d9d 100644 --- a/hw/arm/aspeed_ast27x0_evb.c +++ b/hw/arm/aspeed_ast27x0_evb.c @@ -75,13 +75,13 @@ static const TypeInfo aspeed_ast27x0_evb_types[] = { .name = MACHINE_TYPE_NAME("ast2700a1-evb"), .parent = TYPE_ASPEED_MACHINE, .class_init = aspeed_machine_ast2700a1_evb_class_init, - .is_available = target_aarch64, + .is_available = target_is_aarch64, }, { .name = MACHINE_TYPE_NAME("ast2700a2-evb"), .parent = TYPE_ASPEED_MACHINE, .class_init = aspeed_machine_ast2700a2_evb_class_init, - .is_available = target_aarch64, + .is_available = target_is_aarch64, } }; diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index fadbacb2534..22b06c6ca22 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -403,12 +403,12 @@ static const TypeInfo raspi_machine_types[] = { .name = MACHINE_TYPE_NAME("raspi3ap"), .parent = TYPE_RASPI_MACHINE, .class_init = raspi3ap_machine_class_init, - .is_available = target_aarch64, + .is_available = target_is_aarch64, }, { .name = MACHINE_TYPE_NAME("raspi3b"), .parent = TYPE_RASPI_MACHINE, .class_init = raspi3b_machine_class_init, - .is_available = target_aarch64, + .is_available = target_is_aarch64, }, { .name = TYPE_RASPI_MACHINE, .parent = TYPE_RASPI_BASE_MACHINE, diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c index 566d64572db..a1dc477f25e 100644 --- a/hw/arm/raspi4b.c +++ b/hw/arm/raspi4b.c @@ -121,7 +121,7 @@ static const TypeInfo raspi4b_machine_type = { .parent = TYPE_RASPI_BASE_MACHINE, .instance_size = sizeof(Raspi4bMachineState), .class_init = raspi4b_machine_class_init, - .is_available = target_aarch64, + .is_available = target_is_aarch64, }; static void raspi4b_machine_register_type(void) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 9d192515d85..18160f7fad3 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -132,7 +132,7 @@ static void arm_virt_compat_default_set(MachineClass *mc) .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ .parent = TYPE_VIRT_MACHINE, \ .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ - .is_available = target_base_arm, \ + .is_available = target_is_base_arm, \ }; \ static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ { \ @@ -4430,7 +4430,7 @@ static const TypeInfo virt_machine_info = { { TYPE_HOTPLUG_HANDLER }, { } }, - .is_available = target_base_arm, + .is_available = target_is_base_arm, }; static void machvirt_machine_init(void) diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c index e52546e4fab..ad2a43ef3fb 100644 --- a/hw/m68k/virt.c +++ b/hw/m68k/virt.c @@ -327,7 +327,7 @@ static const TypeInfo virt_machine_info = { .parent = TYPE_MACHINE, .abstract = true, .class_init = virt_machine_class_init, - .is_available = target_m68k, + .is_available = target_is_m68k, }; static void virt_machine_register_types(void) @@ -355,7 +355,7 @@ type_init(virt_machine_register_types) .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ .parent = MACHINE_TYPE_NAME("virt"), \ .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ - .is_available = target_m68k, \ + .is_available = target_is_m68k, \ }; \ static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ { \ diff --git a/hw/or1k/virt.c b/hw/or1k/virt.c index a3ff903839b..89fb786641f 100644 --- a/hw/or1k/virt.c +++ b/hw/or1k/virt.c @@ -559,7 +559,7 @@ static const TypeInfo or1ksim_machine_typeinfo = { .parent = TYPE_MACHINE, .class_init = openrisc_virt_machine_init, .instance_size = sizeof(OR1KVirtState), - .is_available = target_or1k, + .is_available = target_is_or1k, }; static void or1ksim_machine_init_register_types(void) diff --git a/include/qom/object.h b/include/qom/object.h index 4c0645817a5..7d52a15f6b8 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -17,6 +17,7 @@ #include "qapi/qapi-builtin-types.h" #include "qemu/module.h" +typedef struct TargetInfo TargetInfo; struct TypeImpl; typedef struct TypeImpl *Type; @@ -117,6 +118,15 @@ typedef void (ObjectUnparent)(Object *obj); */ typedef void (ObjectFree)(void *obj); +/** + * typedef TypeIsAvailable: + * @ti: TargetInfo to test. + * + * Returns whether a type is available for @ti. Typical implementations + * are target_is_*(). + */ +typedef bool (TypeIsAvailable)(const TargetInfo *ti); + #define OBJECT_CLASS_CAST_CACHE 4 /** @@ -498,7 +508,7 @@ struct TypeInfo void (*class_base_init)(ObjectClass *klass, const void *data); const void *class_data; - bool (*is_available)(void); + TypeIsAvailable *is_available; const InterfaceInfo *interfaces; }; diff --git a/qom/object.c b/qom/object.c index 96498f3d001..253b9562b41 100644 --- a/qom/object.c +++ b/qom/object.c @@ -15,6 +15,7 @@ #include "qom/compat-properties.h" #include "qom/object.h" #include "qom/object_interfaces.h" +#include "qemu/target-info.h" #include "qemu/cutils.h" #include "qemu/memalign.h" #include "qapi/visitor.h" @@ -167,7 +168,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info) abort(); } - if (info->is_available && !info->is_available()) { + if (info->is_available && !info->is_available(target_info())) { return NULL; } -- 2.55.0.windows.3 ^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-07 11:48 ` [PATCH 8/8] qom: pass TargetInfo to is_available for later use Yonggang Luo @ 2026-10-07 20:44 ` Pierrick Bouvier 2026-10-07 21:42 ` Yonggang Luo 0 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-07 20:44 UTC (permalink / raw) To: Yonggang Luo, qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/7/2026 4:48 AM, Yonggang Luo wrote: > Change TypeInfo.is_available to the new TypeIsAvailable type, which > takes a const TargetInfo *. Registration passes target_info(), so > behavior is unchanged. object.h only forward-declares TargetInfo. > > Switch the existing users (raspi, raspi4b, ast27x0 evb and fc) and the > generated machine parents to the matching target_is_<arch> helpers. > > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > --- > hw/arm/aspeed_ast27x0-fc.c | 2 +- > hw/arm/aspeed_ast27x0_evb.c | 4 ++-- > hw/arm/raspi.c | 4 ++-- > hw/arm/raspi4b.c | 2 +- > hw/arm/virt.c | 4 ++-- > hw/m68k/virt.c | 4 ++-- > hw/or1k/virt.c | 2 +- > include/qom/object.h | 12 +++++++++++- > qom/object.c | 3 ++- > 9 files changed, 24 insertions(+), 13 deletions(-) > > diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c > index 73362b60d2a..8a7c6a116ac 100644 > --- a/hw/arm/aspeed_ast27x0-fc.c > +++ b/hw/arm/aspeed_ast27x0-fc.c > @@ -234,7 +234,7 @@ static const TypeInfo ast2700fc_types[] = { > .parent = TYPE_MACHINE, > .class_init = ast2700fc_class_init, > .instance_size = sizeof(Ast2700FCState), > - .is_available = target_aarch64, > + .is_available = target_is_aarch64, > }, > }; > > diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c > index 460c9ff0d2e..02a8cff1d9d 100644 > --- a/hw/arm/aspeed_ast27x0_evb.c > +++ b/hw/arm/aspeed_ast27x0_evb.c > @@ -75,13 +75,13 @@ static const TypeInfo aspeed_ast27x0_evb_types[] = { > .name = MACHINE_TYPE_NAME("ast2700a1-evb"), > .parent = TYPE_ASPEED_MACHINE, > .class_init = aspeed_machine_ast2700a1_evb_class_init, > - .is_available = target_aarch64, > + .is_available = target_is_aarch64, > }, > { > .name = MACHINE_TYPE_NAME("ast2700a2-evb"), > .parent = TYPE_ASPEED_MACHINE, > .class_init = aspeed_machine_ast2700a2_evb_class_init, > - .is_available = target_aarch64, > + .is_available = target_is_aarch64, > } > }; > > diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c > index fadbacb2534..22b06c6ca22 100644 > --- a/hw/arm/raspi.c > +++ b/hw/arm/raspi.c > @@ -403,12 +403,12 @@ static const TypeInfo raspi_machine_types[] = { > .name = MACHINE_TYPE_NAME("raspi3ap"), > .parent = TYPE_RASPI_MACHINE, > .class_init = raspi3ap_machine_class_init, > - .is_available = target_aarch64, > + .is_available = target_is_aarch64, > }, { > .name = MACHINE_TYPE_NAME("raspi3b"), > .parent = TYPE_RASPI_MACHINE, > .class_init = raspi3b_machine_class_init, > - .is_available = target_aarch64, > + .is_available = target_is_aarch64, > }, { > .name = TYPE_RASPI_MACHINE, > .parent = TYPE_RASPI_BASE_MACHINE, > diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c > index 566d64572db..a1dc477f25e 100644 > --- a/hw/arm/raspi4b.c > +++ b/hw/arm/raspi4b.c > @@ -121,7 +121,7 @@ static const TypeInfo raspi4b_machine_type = { > .parent = TYPE_RASPI_BASE_MACHINE, > .instance_size = sizeof(Raspi4bMachineState), > .class_init = raspi4b_machine_class_init, > - .is_available = target_aarch64, > + .is_available = target_is_aarch64, > }; > > static void raspi4b_machine_register_type(void) > diff --git a/hw/arm/virt.c b/hw/arm/virt.c > index 9d192515d85..18160f7fad3 100644 > --- a/hw/arm/virt.c > +++ b/hw/arm/virt.c > @@ -132,7 +132,7 @@ static void arm_virt_compat_default_set(MachineClass *mc) > .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ > .parent = TYPE_VIRT_MACHINE, \ > .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ > - .is_available = target_base_arm, \ > + .is_available = target_is_base_arm, \ > }; \ > static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ > { \ > @@ -4430,7 +4430,7 @@ static const TypeInfo virt_machine_info = { > { TYPE_HOTPLUG_HANDLER }, > { } > }, > - .is_available = target_base_arm, > + .is_available = target_is_base_arm, > }; > > static void machvirt_machine_init(void) > diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c > index e52546e4fab..ad2a43ef3fb 100644 > --- a/hw/m68k/virt.c > +++ b/hw/m68k/virt.c > @@ -327,7 +327,7 @@ static const TypeInfo virt_machine_info = { > .parent = TYPE_MACHINE, > .abstract = true, > .class_init = virt_machine_class_init, > - .is_available = target_m68k, > + .is_available = target_is_m68k, > }; > > static void virt_machine_register_types(void) > @@ -355,7 +355,7 @@ type_init(virt_machine_register_types) > .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ > .parent = MACHINE_TYPE_NAME("virt"), \ > .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ > - .is_available = target_m68k, \ > + .is_available = target_is_m68k, \ > }; \ > static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ > { \ > diff --git a/hw/or1k/virt.c b/hw/or1k/virt.c > index a3ff903839b..89fb786641f 100644 > --- a/hw/or1k/virt.c > +++ b/hw/or1k/virt.c > @@ -559,7 +559,7 @@ static const TypeInfo or1ksim_machine_typeinfo = { > .parent = TYPE_MACHINE, > .class_init = openrisc_virt_machine_init, > .instance_size = sizeof(OR1KVirtState), > - .is_available = target_or1k, > + .is_available = target_is_or1k, > }; > > static void or1ksim_machine_init_register_types(void) > diff --git a/include/qom/object.h b/include/qom/object.h > index 4c0645817a5..7d52a15f6b8 100644 > --- a/include/qom/object.h > +++ b/include/qom/object.h > @@ -17,6 +17,7 @@ > #include "qapi/qapi-builtin-types.h" > #include "qemu/module.h" > > +typedef struct TargetInfo TargetInfo; > struct TypeImpl; > typedef struct TypeImpl *Type; > > @@ -117,6 +118,15 @@ typedef void (ObjectUnparent)(Object *obj); > */ > typedef void (ObjectFree)(void *obj); > > +/** > + * typedef TypeIsAvailable: > + * @ti: TargetInfo to test. > + * > + * Returns whether a type is available for @ti. Typical implementations > + * are target_is_*(). > + */ > +typedef bool (TypeIsAvailable)(const TargetInfo *ti); > + > #define OBJECT_CLASS_CAST_CACHE 4 > > /** > @@ -498,7 +508,7 @@ struct TypeInfo > void (*class_base_init)(ObjectClass *klass, const void *data); > const void *class_data; > > - bool (*is_available)(void); > + TypeIsAvailable *is_available; > const InterfaceInfo *interfaces; > }; > > diff --git a/qom/object.c b/qom/object.c > index 96498f3d001..253b9562b41 100644 > --- a/qom/object.c > +++ b/qom/object.c > @@ -15,6 +15,7 @@ > #include "qom/compat-properties.h" > #include "qom/object.h" > #include "qom/object_interfaces.h" > +#include "qemu/target-info.h" > #include "qemu/cutils.h" > #include "qemu/memalign.h" > #include "qapi/visitor.h" > @@ -167,7 +168,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info) > abort(); > } > > - if (info->is_available && !info->is_available()) { > + if (info->is_available && !info->is_available(target_info())) { > return NULL; > } > ``` info->is_available(target_info()) ``` or ``` is_available() { TargetInfo ti * = target_info(); ... } ``` Are doing the exact same thing today. So what is the future goal requiring to introduce this? It's something we asked multiple times, and until we don't have a short series doing this change + a single and minimal modification showing the reason, I will still be asking. If the goal is to implement some sort of classification for machines/cpus, I would suggest to just send a simple series doing this change (and only this - no additional cleanups/refactoring), and an example for a single machine + cpu, so we can talk about it. Regards, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-07 20:44 ` Pierrick Bouvier @ 2026-10-07 21:42 ` Yonggang Luo 2026-10-08 0:00 ` Pierrick Bouvier 0 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-07 21:42 UTC (permalink / raw) To: Pierrick Bouvier Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Thu, Oct 8, 2026 at 4:44 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/7/2026 4:48 AM, Yonggang Luo wrote: > > Change TypeInfo.is_available to the new TypeIsAvailable type, which > > takes a const TargetInfo *. Registration passes target_info(), so > > behavior is unchanged. object.h only forward-declares TargetInfo. > > > > Switch the existing users (raspi, raspi4b, ast27x0 evb and fc) and the > > generated machine parents to the matching target_is_<arch> helpers. > > > > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > > --- > > hw/arm/aspeed_ast27x0-fc.c | 2 +- > > hw/arm/aspeed_ast27x0_evb.c | 4 ++-- > > hw/arm/raspi.c | 4 ++-- > > hw/arm/raspi4b.c | 2 +- > > hw/arm/virt.c | 4 ++-- > > hw/m68k/virt.c | 4 ++-- > > hw/or1k/virt.c | 2 +- > > include/qom/object.h | 12 +++++++++++- > > qom/object.c | 3 ++- > > 9 files changed, 24 insertions(+), 13 deletions(-) > > > > diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c > > index 73362b60d2a..8a7c6a116ac 100644 > > --- a/hw/arm/aspeed_ast27x0-fc.c > > +++ b/hw/arm/aspeed_ast27x0-fc.c > > @@ -234,7 +234,7 @@ static const TypeInfo ast2700fc_types[] = { > > .parent = TYPE_MACHINE, > > .class_init = ast2700fc_class_init, > > .instance_size = sizeof(Ast2700FCState), > > - .is_available = target_aarch64, > > + .is_available = target_is_aarch64, > > }, > > }; > > > > diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c > > index 460c9ff0d2e..02a8cff1d9d 100644 > > --- a/hw/arm/aspeed_ast27x0_evb.c > > +++ b/hw/arm/aspeed_ast27x0_evb.c > > @@ -75,13 +75,13 @@ static const TypeInfo aspeed_ast27x0_evb_types[] = { > > .name = MACHINE_TYPE_NAME("ast2700a1-evb"), > > .parent = TYPE_ASPEED_MACHINE, > > .class_init = aspeed_machine_ast2700a1_evb_class_init, > > - .is_available = target_aarch64, > > + .is_available = target_is_aarch64, > > }, > > { > > .name = MACHINE_TYPE_NAME("ast2700a2-evb"), > > .parent = TYPE_ASPEED_MACHINE, > > .class_init = aspeed_machine_ast2700a2_evb_class_init, > > - .is_available = target_aarch64, > > + .is_available = target_is_aarch64, > > } > > }; > > > > diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c > > index fadbacb2534..22b06c6ca22 100644 > > --- a/hw/arm/raspi.c > > +++ b/hw/arm/raspi.c > > @@ -403,12 +403,12 @@ static const TypeInfo raspi_machine_types[] = { > > .name = MACHINE_TYPE_NAME("raspi3ap"), > > .parent = TYPE_RASPI_MACHINE, > > .class_init = raspi3ap_machine_class_init, > > - .is_available = target_aarch64, > > + .is_available = target_is_aarch64, > > }, { > > .name = MACHINE_TYPE_NAME("raspi3b"), > > .parent = TYPE_RASPI_MACHINE, > > .class_init = raspi3b_machine_class_init, > > - .is_available = target_aarch64, > > + .is_available = target_is_aarch64, > > }, { > > .name = TYPE_RASPI_MACHINE, > > .parent = TYPE_RASPI_BASE_MACHINE, > > diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c > > index 566d64572db..a1dc477f25e 100644 > > --- a/hw/arm/raspi4b.c > > +++ b/hw/arm/raspi4b.c > > @@ -121,7 +121,7 @@ static const TypeInfo raspi4b_machine_type = { > > .parent = TYPE_RASPI_BASE_MACHINE, > > .instance_size = sizeof(Raspi4bMachineState), > > .class_init = raspi4b_machine_class_init, > > - .is_available = target_aarch64, > > + .is_available = target_is_aarch64, > > }; > > > > static void raspi4b_machine_register_type(void) > > diff --git a/hw/arm/virt.c b/hw/arm/virt.c > > index 9d192515d85..18160f7fad3 100644 > > --- a/hw/arm/virt.c > > +++ b/hw/arm/virt.c > > @@ -132,7 +132,7 @@ static void arm_virt_compat_default_set(MachineClass *mc) > > .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ > > .parent = TYPE_VIRT_MACHINE, \ > > .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ > > - .is_available = target_base_arm, \ > > + .is_available = target_is_base_arm, \ > > }; \ > > static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ > > { \ > > @@ -4430,7 +4430,7 @@ static const TypeInfo virt_machine_info = { > > { TYPE_HOTPLUG_HANDLER }, > > { } > > }, > > - .is_available = target_base_arm, > > + .is_available = target_is_base_arm, > > }; > > > > static void machvirt_machine_init(void) > > diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c > > index e52546e4fab..ad2a43ef3fb 100644 > > --- a/hw/m68k/virt.c > > +++ b/hw/m68k/virt.c > > @@ -327,7 +327,7 @@ static const TypeInfo virt_machine_info = { > > .parent = TYPE_MACHINE, > > .abstract = true, > > .class_init = virt_machine_class_init, > > - .is_available = target_m68k, > > + .is_available = target_is_m68k, > > }; > > > > static void virt_machine_register_types(void) > > @@ -355,7 +355,7 @@ type_init(virt_machine_register_types) > > .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ > > .parent = MACHINE_TYPE_NAME("virt"), \ > > .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ > > - .is_available = target_m68k, \ > > + .is_available = target_is_m68k, \ > > }; \ > > static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ > > { \ > > diff --git a/hw/or1k/virt.c b/hw/or1k/virt.c > > index a3ff903839b..89fb786641f 100644 > > --- a/hw/or1k/virt.c > > +++ b/hw/or1k/virt.c > > @@ -559,7 +559,7 @@ static const TypeInfo or1ksim_machine_typeinfo = { > > .parent = TYPE_MACHINE, > > .class_init = openrisc_virt_machine_init, > > .instance_size = sizeof(OR1KVirtState), > > - .is_available = target_or1k, > > + .is_available = target_is_or1k, > > }; > > > > static void or1ksim_machine_init_register_types(void) > > diff --git a/include/qom/object.h b/include/qom/object.h > > index 4c0645817a5..7d52a15f6b8 100644 > > --- a/include/qom/object.h > > +++ b/include/qom/object.h > > @@ -17,6 +17,7 @@ > > #include "qapi/qapi-builtin-types.h" > > #include "qemu/module.h" > > > > +typedef struct TargetInfo TargetInfo; > > struct TypeImpl; > > typedef struct TypeImpl *Type; > > > > @@ -117,6 +118,15 @@ typedef void (ObjectUnparent)(Object *obj); > > */ > > typedef void (ObjectFree)(void *obj); > > > > +/** > > + * typedef TypeIsAvailable: > > + * @ti: TargetInfo to test. > > + * > > + * Returns whether a type is available for @ti. Typical implementations > > + * are target_is_*(). > > + */ > > +typedef bool (TypeIsAvailable)(const TargetInfo *ti); > > + > > #define OBJECT_CLASS_CAST_CACHE 4 > > > > /** > > @@ -498,7 +508,7 @@ struct TypeInfo > > void (*class_base_init)(ObjectClass *klass, const void *data); > > const void *class_data; > > > > - bool (*is_available)(void); > > + TypeIsAvailable *is_available; > > const InterfaceInfo *interfaces; > > }; > > > > diff --git a/qom/object.c b/qom/object.c > > index 96498f3d001..253b9562b41 100644 > > --- a/qom/object.c > > +++ b/qom/object.c > > @@ -15,6 +15,7 @@ > > #include "qom/compat-properties.h" > > #include "qom/object.h" > > #include "qom/object_interfaces.h" > > +#include "qemu/target-info.h" > > #include "qemu/cutils.h" > > #include "qemu/memalign.h" > > #include "qapi/visitor.h" > > @@ -167,7 +168,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info) > > abort(); > > } > > > > - if (info->is_available && !info->is_available()) { > > + if (info->is_available && !info->is_available(target_info())) { > > return NULL; > > } > > > > ``` > info->is_available(target_info()) > ``` > > or > > ``` > is_available() { > TargetInfo ti * = target_info(); > ... > } > ``` > > Are doing the exact same thing today. > > So what is the future goal requiring to introduce this? From Daniel P. Berrangé's requesthttps://lore.kernel.org/qemu-devel/apAszS1ewxM0Y1XU@redhat.com/ I forgot to mention that this is also pretty important for making introspection work, as we need to be able to say 'qemu-system --machine none -qmp ...' and connect to QMP to introspect the binary. Having to add a '--target <name>' into that mix is undesirable, as it creates a chicken & egg problem. You don't know what targets are built into qemu-system without introspecting it and you can't introspect it without selecting a target to introspect. From Pierrick's review https://lore.kernel.org/qemu-devel/557262df-b8e7-49b5-a245-ae46b8885b30@oss.qualcomm.com/So, for existing binary: -M virt works as before. For new multi binary: $ qemu-system -M virt: Multiple machines were found, select one among: - aarch64-virt - riscv64-virt Does it matches what you would expect? From Daniel's review https://lore.kernel.org/qemu-devel/aro93NuZBXYGbD33@redhat.com/ We already have 'QemuTargetInfo' struct which is used with 'query-target', that should also be used with the new 'query-targets' command. We need to add the 'endianness' field to QemuTargetInfo. I don't think that we need to report machines though. We already have 'query-machines' which gives much broader information on the machines. "MachineInfo" needs to gain "targets": ["SysEmuTarget"] to list which target(s) a machine can be used with. To achieve these, we needs add TypeInfo parameter to it so that we can do static void report_unsupported_machine_type(const char *name, Error **errp) { g_autoptr(GSList) machines = machine_class_get_list(true); g_autoptr(GString) targets = g_string_new(NULL); TargetInfoNode *node; GSList *el; error_setg(errp, "unsupported machine type: \"%s\" for target \"%s\"", name, target_name()); QLIST_FOREACH(node, target_info_list(), next) { for (el = machines; el; el = el->next) { MachineClass *mc = el->data; if ((!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) && object_class_get_is_available(OBJECT_CLASS(mc))(node->info)) { g_string_append_printf(targets, " %s\n", node->info->target_name); break; } } } if (targets->len) { error_append_hint(errp, "Available for targets:\n%s", targets->str); } } That is we can iterate on all target-list, and check if it's can be fitlered. > > It's something we asked multiple times, and until we don't have a short > series doing this change + a single and minimal modification showing the > reason, I will still be asking. > > If the goal is to implement some sort of classification for > machines/cpus, I would suggest to just send a simple series doing this > change (and only this - no additional cleanups/refactoring), and an > example for a single machine + cpu, so we can talk about it. > > Regards, > Pierrick -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-07 21:42 ` Yonggang Luo @ 2026-10-08 0:00 ` Pierrick Bouvier 2026-10-08 0:03 ` Pierrick Bouvier ` (2 more replies) 0 siblings, 3 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-08 0:00 UTC (permalink / raw) To: luoyonggang Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/7/2026 2:42 PM, Yonggang Luo wrote: > On Thu, Oct 8, 2026 at 4:44 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> wrote: >> >> On 10/7/2026 4:48 AM, Yonggang Luo wrote: >>> Change TypeInfo.is_available to the new TypeIsAvailable type, which >>> takes a const TargetInfo *. Registration passes target_info(), so >>> behavior is unchanged. object.h only forward-declares TargetInfo. >>> >>> Switch the existing users (raspi, raspi4b, ast27x0 evb and fc) and the >>> generated machine parents to the matching target_is_<arch> helpers. >>> >>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> >>> --- >>> hw/arm/aspeed_ast27x0-fc.c | 2 +- >>> hw/arm/aspeed_ast27x0_evb.c | 4 ++-- >>> hw/arm/raspi.c | 4 ++-- >>> hw/arm/raspi4b.c | 2 +- >>> hw/arm/virt.c | 4 ++-- >>> hw/m68k/virt.c | 4 ++-- >>> hw/or1k/virt.c | 2 +- >>> include/qom/object.h | 12 +++++++++++- >>> qom/object.c | 3 ++- >>> 9 files changed, 24 insertions(+), 13 deletions(-) >>> >>> diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c >>> index 73362b60d2a..8a7c6a116ac 100644 >>> --- a/hw/arm/aspeed_ast27x0-fc.c >>> +++ b/hw/arm/aspeed_ast27x0-fc.c >>> @@ -234,7 +234,7 @@ static const TypeInfo ast2700fc_types[] = { >>> .parent = TYPE_MACHINE, >>> .class_init = ast2700fc_class_init, >>> .instance_size = sizeof(Ast2700FCState), >>> - .is_available = target_aarch64, >>> + .is_available = target_is_aarch64, >>> }, >>> }; >>> >>> diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c >>> index 460c9ff0d2e..02a8cff1d9d 100644 >>> --- a/hw/arm/aspeed_ast27x0_evb.c >>> +++ b/hw/arm/aspeed_ast27x0_evb.c >>> @@ -75,13 +75,13 @@ static const TypeInfo aspeed_ast27x0_evb_types[] = { >>> .name = MACHINE_TYPE_NAME("ast2700a1-evb"), >>> .parent = TYPE_ASPEED_MACHINE, >>> .class_init = aspeed_machine_ast2700a1_evb_class_init, >>> - .is_available = target_aarch64, >>> + .is_available = target_is_aarch64, >>> }, >>> { >>> .name = MACHINE_TYPE_NAME("ast2700a2-evb"), >>> .parent = TYPE_ASPEED_MACHINE, >>> .class_init = aspeed_machine_ast2700a2_evb_class_init, >>> - .is_available = target_aarch64, >>> + .is_available = target_is_aarch64, >>> } >>> }; >>> >>> diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c >>> index fadbacb2534..22b06c6ca22 100644 >>> --- a/hw/arm/raspi.c >>> +++ b/hw/arm/raspi.c >>> @@ -403,12 +403,12 @@ static const TypeInfo raspi_machine_types[] = { >>> .name = MACHINE_TYPE_NAME("raspi3ap"), >>> .parent = TYPE_RASPI_MACHINE, >>> .class_init = raspi3ap_machine_class_init, >>> - .is_available = target_aarch64, >>> + .is_available = target_is_aarch64, >>> }, { >>> .name = MACHINE_TYPE_NAME("raspi3b"), >>> .parent = TYPE_RASPI_MACHINE, >>> .class_init = raspi3b_machine_class_init, >>> - .is_available = target_aarch64, >>> + .is_available = target_is_aarch64, >>> }, { >>> .name = TYPE_RASPI_MACHINE, >>> .parent = TYPE_RASPI_BASE_MACHINE, >>> diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c >>> index 566d64572db..a1dc477f25e 100644 >>> --- a/hw/arm/raspi4b.c >>> +++ b/hw/arm/raspi4b.c >>> @@ -121,7 +121,7 @@ static const TypeInfo raspi4b_machine_type = { >>> .parent = TYPE_RASPI_BASE_MACHINE, >>> .instance_size = sizeof(Raspi4bMachineState), >>> .class_init = raspi4b_machine_class_init, >>> - .is_available = target_aarch64, >>> + .is_available = target_is_aarch64, >>> }; >>> >>> static void raspi4b_machine_register_type(void) >>> diff --git a/hw/arm/virt.c b/hw/arm/virt.c >>> index 9d192515d85..18160f7fad3 100644 >>> --- a/hw/arm/virt.c >>> +++ b/hw/arm/virt.c >>> @@ -132,7 +132,7 @@ static void arm_virt_compat_default_set(MachineClass *mc) >>> .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ >>> .parent = TYPE_VIRT_MACHINE, \ >>> .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ >>> - .is_available = target_base_arm, \ >>> + .is_available = target_is_base_arm, \ >>> }; \ >>> static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ >>> { \ >>> @@ -4430,7 +4430,7 @@ static const TypeInfo virt_machine_info = { >>> { TYPE_HOTPLUG_HANDLER }, >>> { } >>> }, >>> - .is_available = target_base_arm, >>> + .is_available = target_is_base_arm, >>> }; >>> >>> static void machvirt_machine_init(void) >>> diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c >>> index e52546e4fab..ad2a43ef3fb 100644 >>> --- a/hw/m68k/virt.c >>> +++ b/hw/m68k/virt.c >>> @@ -327,7 +327,7 @@ static const TypeInfo virt_machine_info = { >>> .parent = TYPE_MACHINE, >>> .abstract = true, >>> .class_init = virt_machine_class_init, >>> - .is_available = target_m68k, >>> + .is_available = target_is_m68k, >>> }; >>> >>> static void virt_machine_register_types(void) >>> @@ -355,7 +355,7 @@ type_init(virt_machine_register_types) >>> .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ >>> .parent = MACHINE_TYPE_NAME("virt"), \ >>> .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ >>> - .is_available = target_m68k, \ >>> + .is_available = target_is_m68k, \ >>> }; \ >>> static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ >>> { \ >>> diff --git a/hw/or1k/virt.c b/hw/or1k/virt.c >>> index a3ff903839b..89fb786641f 100644 >>> --- a/hw/or1k/virt.c >>> +++ b/hw/or1k/virt.c >>> @@ -559,7 +559,7 @@ static const TypeInfo or1ksim_machine_typeinfo = { >>> .parent = TYPE_MACHINE, >>> .class_init = openrisc_virt_machine_init, >>> .instance_size = sizeof(OR1KVirtState), >>> - .is_available = target_or1k, >>> + .is_available = target_is_or1k, >>> }; >>> >>> static void or1ksim_machine_init_register_types(void) >>> diff --git a/include/qom/object.h b/include/qom/object.h >>> index 4c0645817a5..7d52a15f6b8 100644 >>> --- a/include/qom/object.h >>> +++ b/include/qom/object.h >>> @@ -17,6 +17,7 @@ >>> #include "qapi/qapi-builtin-types.h" >>> #include "qemu/module.h" >>> >>> +typedef struct TargetInfo TargetInfo; >>> struct TypeImpl; >>> typedef struct TypeImpl *Type; >>> >>> @@ -117,6 +118,15 @@ typedef void (ObjectUnparent)(Object *obj); >>> */ >>> typedef void (ObjectFree)(void *obj); >>> >>> +/** >>> + * typedef TypeIsAvailable: >>> + * @ti: TargetInfo to test. >>> + * >>> + * Returns whether a type is available for @ti. Typical implementations >>> + * are target_is_*(). >>> + */ >>> +typedef bool (TypeIsAvailable)(const TargetInfo *ti); >>> + >>> #define OBJECT_CLASS_CAST_CACHE 4 >>> >>> /** >>> @@ -498,7 +508,7 @@ struct TypeInfo >>> void (*class_base_init)(ObjectClass *klass, const void *data); >>> const void *class_data; >>> >>> - bool (*is_available)(void); >>> + TypeIsAvailable *is_available; >>> const InterfaceInfo *interfaces; >>> }; >>> >>> diff --git a/qom/object.c b/qom/object.c >>> index 96498f3d001..253b9562b41 100644 >>> --- a/qom/object.c >>> +++ b/qom/object.c >>> @@ -15,6 +15,7 @@ >>> #include "qom/compat-properties.h" >>> #include "qom/object.h" >>> #include "qom/object_interfaces.h" >>> +#include "qemu/target-info.h" >>> #include "qemu/cutils.h" >>> #include "qemu/memalign.h" >>> #include "qapi/visitor.h" >>> @@ -167,7 +168,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info) >>> abort(); >>> } >>> >>> - if (info->is_available && !info->is_available()) { >>> + if (info->is_available && !info->is_available(target_info())) { >>> return NULL; >>> } >>> >> >> ``` >> info->is_available(target_info()) >> ``` >> >> or >> >> ``` >> is_available() { >> TargetInfo ti * = target_info(); >> ... >> } >> ``` >> >> Are doing the exact same thing today. >> >> So what is the future goal requiring to introduce this? > > From Daniel P. Berrangé's > requesthttps://lore.kernel.org/qemu-devel/apAszS1ewxM0Y1XU@redhat.com/ > I forgot to mention that this is also pretty important for making > introspection work, as we need to be able to say > > 'qemu-system --machine none -qmp ...' > > and connect to QMP to introspect the binary. Having to add a > '--target <name>' into that mix is undesirable, as it creates > a chicken & egg problem. You don't know what targets are built > into qemu-system without introspecting it and you can't > introspect it without selecting a target to introspect. > > From Pierrick's review > https://lore.kernel.org/qemu-devel/557262df-b8e7-49b5-a245-ae46b8885b30@oss.qualcomm.com/So, > for existing binary: -M virt works as before. > > For new multi binary: > $ qemu-system -M virt: > Multiple machines were found, select one among: > - aarch64-virt > - riscv64-virt > > Does it matches what you would expect? > > From Daniel's review > https://lore.kernel.org/qemu-devel/aro93NuZBXYGbD33@redhat.com/ > We already have 'QemuTargetInfo' struct which is used > with 'query-target', that should also be used with the > new 'query-targets' command. > > We need to add the 'endianness' field to QemuTargetInfo. > > I don't think that we need to report machines though. > We already have 'query-machines' which gives much broader > information on the machines. "MachineInfo" needs to > gain > > "targets": ["SysEmuTarget"] > > to list which target(s) a machine can be used with. > > > To achieve these, we needs add TypeInfo parameter to it so that we can do > > static void report_unsupported_machine_type(const char *name, Error **errp) > { > g_autoptr(GSList) machines = machine_class_get_list(true); > g_autoptr(GString) targets = g_string_new(NULL); > TargetInfoNode *node; > GSList *el; > > error_setg(errp, "unsupported machine type: \"%s\" for target \"%s\"", > name, target_name()); > QLIST_FOREACH(node, target_info_list(), next) { > for (el = machines; el; el = el->next) { > MachineClass *mc = el->data; > > if ((!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) && > object_class_get_is_available(OBJECT_CLASS(mc))(node->info)) { > g_string_append_printf(targets, " %s\n", > node->info->target_name); > break; > } > } > } > if (targets->len) { > error_append_hint(errp, "Available for targets:\n%s", targets->str); > } > } > > That is we can iterate on all target-list, and check if it's can be fitlered. > Ok, I finally see where this is going. 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? It's what we did in the past (https://gitlab.com/qemu-project/qemu/-/commit/5de9216064d32eaac125dac4de1878486c16d73e), 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; ``` @Daniel, IIUC, this is exactly the approach you proposed a few weeks ago, just before I got frustrated and lost my patience against you. I think it's more clear for me where you wanted to go. Sorry it took such a large detour. Yonggang, does that sounds good for you? Daniel, does that sounds good for you also? Regards, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-08 0:00 ` Pierrick Bouvier @ 2026-10-08 0:03 ` Pierrick Bouvier 2026-10-08 2:08 ` Yonggang Luo 2026-10-08 9:36 ` Daniel P. Berrangé 2 siblings, 0 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-08 0:03 UTC (permalink / raw) To: luoyonggang Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/7/2026 5:00 PM, Pierrick Bouvier wrote: > On 10/7/2026 2:42 PM, Yonggang Luo wrote: >> On Thu, Oct 8, 2026 at 4:44 AM Pierrick Bouvier >> <pierrick.bouvier@oss.qualcomm.com> wrote: >>> >>> On 10/7/2026 4:48 AM, Yonggang Luo wrote: >>>> Change TypeInfo.is_available to the new TypeIsAvailable type, which >>>> takes a const TargetInfo *. Registration passes target_info(), so >>>> behavior is unchanged. object.h only forward-declares TargetInfo. >>>> >>>> Switch the existing users (raspi, raspi4b, ast27x0 evb and fc) and the >>>> generated machine parents to the matching target_is_<arch> helpers. >>>> >>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> >>>> --- >>>> hw/arm/aspeed_ast27x0-fc.c | 2 +- >>>> hw/arm/aspeed_ast27x0_evb.c | 4 ++-- >>>> hw/arm/raspi.c | 4 ++-- >>>> hw/arm/raspi4b.c | 2 +- >>>> hw/arm/virt.c | 4 ++-- >>>> hw/m68k/virt.c | 4 ++-- >>>> hw/or1k/virt.c | 2 +- >>>> include/qom/object.h | 12 +++++++++++- >>>> qom/object.c | 3 ++- >>>> 9 files changed, 24 insertions(+), 13 deletions(-) >>>> >>>> diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c >>>> index 73362b60d2a..8a7c6a116ac 100644 >>>> --- a/hw/arm/aspeed_ast27x0-fc.c >>>> +++ b/hw/arm/aspeed_ast27x0-fc.c >>>> @@ -234,7 +234,7 @@ static const TypeInfo ast2700fc_types[] = { >>>> .parent = TYPE_MACHINE, >>>> .class_init = ast2700fc_class_init, >>>> .instance_size = sizeof(Ast2700FCState), >>>> - .is_available = target_aarch64, >>>> + .is_available = target_is_aarch64, >>>> }, >>>> }; >>>> >>>> diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c >>>> index 460c9ff0d2e..02a8cff1d9d 100644 >>>> --- a/hw/arm/aspeed_ast27x0_evb.c >>>> +++ b/hw/arm/aspeed_ast27x0_evb.c >>>> @@ -75,13 +75,13 @@ static const TypeInfo aspeed_ast27x0_evb_types[] = { >>>> .name = MACHINE_TYPE_NAME("ast2700a1-evb"), >>>> .parent = TYPE_ASPEED_MACHINE, >>>> .class_init = aspeed_machine_ast2700a1_evb_class_init, >>>> - .is_available = target_aarch64, >>>> + .is_available = target_is_aarch64, >>>> }, >>>> { >>>> .name = MACHINE_TYPE_NAME("ast2700a2-evb"), >>>> .parent = TYPE_ASPEED_MACHINE, >>>> .class_init = aspeed_machine_ast2700a2_evb_class_init, >>>> - .is_available = target_aarch64, >>>> + .is_available = target_is_aarch64, >>>> } >>>> }; >>>> >>>> diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c >>>> index fadbacb2534..22b06c6ca22 100644 >>>> --- a/hw/arm/raspi.c >>>> +++ b/hw/arm/raspi.c >>>> @@ -403,12 +403,12 @@ static const TypeInfo raspi_machine_types[] = { >>>> .name = MACHINE_TYPE_NAME("raspi3ap"), >>>> .parent = TYPE_RASPI_MACHINE, >>>> .class_init = raspi3ap_machine_class_init, >>>> - .is_available = target_aarch64, >>>> + .is_available = target_is_aarch64, >>>> }, { >>>> .name = MACHINE_TYPE_NAME("raspi3b"), >>>> .parent = TYPE_RASPI_MACHINE, >>>> .class_init = raspi3b_machine_class_init, >>>> - .is_available = target_aarch64, >>>> + .is_available = target_is_aarch64, >>>> }, { >>>> .name = TYPE_RASPI_MACHINE, >>>> .parent = TYPE_RASPI_BASE_MACHINE, >>>> diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c >>>> index 566d64572db..a1dc477f25e 100644 >>>> --- a/hw/arm/raspi4b.c >>>> +++ b/hw/arm/raspi4b.c >>>> @@ -121,7 +121,7 @@ static const TypeInfo raspi4b_machine_type = { >>>> .parent = TYPE_RASPI_BASE_MACHINE, >>>> .instance_size = sizeof(Raspi4bMachineState), >>>> .class_init = raspi4b_machine_class_init, >>>> - .is_available = target_aarch64, >>>> + .is_available = target_is_aarch64, >>>> }; >>>> >>>> static void raspi4b_machine_register_type(void) >>>> diff --git a/hw/arm/virt.c b/hw/arm/virt.c >>>> index 9d192515d85..18160f7fad3 100644 >>>> --- a/hw/arm/virt.c >>>> +++ b/hw/arm/virt.c >>>> @@ -132,7 +132,7 @@ static void arm_virt_compat_default_set(MachineClass *mc) >>>> .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ >>>> .parent = TYPE_VIRT_MACHINE, \ >>>> .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ >>>> - .is_available = target_base_arm, \ >>>> + .is_available = target_is_base_arm, \ >>>> }; \ >>>> static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ >>>> { \ >>>> @@ -4430,7 +4430,7 @@ static const TypeInfo virt_machine_info = { >>>> { TYPE_HOTPLUG_HANDLER }, >>>> { } >>>> }, >>>> - .is_available = target_base_arm, >>>> + .is_available = target_is_base_arm, >>>> }; >>>> >>>> static void machvirt_machine_init(void) >>>> diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c >>>> index e52546e4fab..ad2a43ef3fb 100644 >>>> --- a/hw/m68k/virt.c >>>> +++ b/hw/m68k/virt.c >>>> @@ -327,7 +327,7 @@ static const TypeInfo virt_machine_info = { >>>> .parent = TYPE_MACHINE, >>>> .abstract = true, >>>> .class_init = virt_machine_class_init, >>>> - .is_available = target_m68k, >>>> + .is_available = target_is_m68k, >>>> }; >>>> >>>> static void virt_machine_register_types(void) >>>> @@ -355,7 +355,7 @@ type_init(virt_machine_register_types) >>>> .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ >>>> .parent = MACHINE_TYPE_NAME("virt"), \ >>>> .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ >>>> - .is_available = target_m68k, \ >>>> + .is_available = target_is_m68k, \ >>>> }; \ >>>> static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ >>>> { \ >>>> diff --git a/hw/or1k/virt.c b/hw/or1k/virt.c >>>> index a3ff903839b..89fb786641f 100644 >>>> --- a/hw/or1k/virt.c >>>> +++ b/hw/or1k/virt.c >>>> @@ -559,7 +559,7 @@ static const TypeInfo or1ksim_machine_typeinfo = { >>>> .parent = TYPE_MACHINE, >>>> .class_init = openrisc_virt_machine_init, >>>> .instance_size = sizeof(OR1KVirtState), >>>> - .is_available = target_or1k, >>>> + .is_available = target_is_or1k, >>>> }; >>>> >>>> static void or1ksim_machine_init_register_types(void) >>>> diff --git a/include/qom/object.h b/include/qom/object.h >>>> index 4c0645817a5..7d52a15f6b8 100644 >>>> --- a/include/qom/object.h >>>> +++ b/include/qom/object.h >>>> @@ -17,6 +17,7 @@ >>>> #include "qapi/qapi-builtin-types.h" >>>> #include "qemu/module.h" >>>> >>>> +typedef struct TargetInfo TargetInfo; >>>> struct TypeImpl; >>>> typedef struct TypeImpl *Type; >>>> >>>> @@ -117,6 +118,15 @@ typedef void (ObjectUnparent)(Object *obj); >>>> */ >>>> typedef void (ObjectFree)(void *obj); >>>> >>>> +/** >>>> + * typedef TypeIsAvailable: >>>> + * @ti: TargetInfo to test. >>>> + * >>>> + * Returns whether a type is available for @ti. Typical implementations >>>> + * are target_is_*(). >>>> + */ >>>> +typedef bool (TypeIsAvailable)(const TargetInfo *ti); >>>> + >>>> #define OBJECT_CLASS_CAST_CACHE 4 >>>> >>>> /** >>>> @@ -498,7 +508,7 @@ struct TypeInfo >>>> void (*class_base_init)(ObjectClass *klass, const void *data); >>>> const void *class_data; >>>> >>>> - bool (*is_available)(void); >>>> + TypeIsAvailable *is_available; >>>> const InterfaceInfo *interfaces; >>>> }; >>>> >>>> diff --git a/qom/object.c b/qom/object.c >>>> index 96498f3d001..253b9562b41 100644 >>>> --- a/qom/object.c >>>> +++ b/qom/object.c >>>> @@ -15,6 +15,7 @@ >>>> #include "qom/compat-properties.h" >>>> #include "qom/object.h" >>>> #include "qom/object_interfaces.h" >>>> +#include "qemu/target-info.h" >>>> #include "qemu/cutils.h" >>>> #include "qemu/memalign.h" >>>> #include "qapi/visitor.h" >>>> @@ -167,7 +168,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info) >>>> abort(); >>>> } >>>> >>>> - if (info->is_available && !info->is_available()) { >>>> + if (info->is_available && !info->is_available(target_info())) { >>>> return NULL; >>>> } >>>> >>> >>> ``` >>> info->is_available(target_info()) >>> ``` >>> >>> or >>> >>> ``` >>> is_available() { >>> TargetInfo ti * = target_info(); >>> ... >>> } >>> ``` >>> >>> Are doing the exact same thing today. >>> >>> So what is the future goal requiring to introduce this? >> >> From Daniel P. Berrangé's >> requesthttps://lore.kernel.org/qemu-devel/apAszS1ewxM0Y1XU@redhat.com/ >> I forgot to mention that this is also pretty important for making >> introspection work, as we need to be able to say >> >> 'qemu-system --machine none -qmp ...' >> >> and connect to QMP to introspect the binary. Having to add a >> '--target <name>' into that mix is undesirable, as it creates >> a chicken & egg problem. You don't know what targets are built >> into qemu-system without introspecting it and you can't >> introspect it without selecting a target to introspect. >> >> From Pierrick's review >> https://lore.kernel.org/qemu-devel/557262df-b8e7-49b5-a245-ae46b8885b30@oss.qualcomm.com/So, >> for existing binary: -M virt works as before. >> >> For new multi binary: >> $ qemu-system -M virt: >> Multiple machines were found, select one among: >> - aarch64-virt >> - riscv64-virt >> >> Does it matches what you would expect? >> >> From Daniel's review >> https://lore.kernel.org/qemu-devel/aro93NuZBXYGbD33@redhat.com/ >> We already have 'QemuTargetInfo' struct which is used >> with 'query-target', that should also be used with the >> new 'query-targets' command. >> >> We need to add the 'endianness' field to QemuTargetInfo. >> >> I don't think that we need to report machines though. >> We already have 'query-machines' which gives much broader >> information on the machines. "MachineInfo" needs to >> gain >> >> "targets": ["SysEmuTarget"] >> >> to list which target(s) a machine can be used with. >> >> >> To achieve these, we needs add TypeInfo parameter to it so that we can do >> >> static void report_unsupported_machine_type(const char *name, Error **errp) >> { >> g_autoptr(GSList) machines = machine_class_get_list(true); >> g_autoptr(GString) targets = g_string_new(NULL); >> TargetInfoNode *node; >> GSList *el; >> >> error_setg(errp, "unsupported machine type: \"%s\" for target \"%s\"", >> name, target_name()); >> QLIST_FOREACH(node, target_info_list(), next) { >> for (el = machines; el; el = el->next) { >> MachineClass *mc = el->data; >> >> if ((!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) && >> object_class_get_is_available(OBJECT_CLASS(mc))(node->info)) { >> g_string_append_printf(targets, " %s\n", >> node->info->target_name); >> break; >> } >> } >> } >> if (targets->len) { >> error_append_hint(errp, "Available for targets:\n%s", targets->str); >> } >> } >> >> That is we can iterate on all target-list, and check if it's can be fitlered. >> > > Ok, I finally see where this is going. > > 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? > > It's what we did in the past > (https://gitlab.com/qemu-project/qemu/-/commit/5de9216064d32eaac125dac4de1878486c16d73e), > 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; > ``` > Machine class more exactly: mc->targets See mc->desc for a concrete example of where it should be set. > @Daniel, IIUC, this is exactly the approach you proposed a few weeks > ago, just before I got frustrated and lost my patience against you. I > think it's more clear for me where you wanted to go. Sorry it took such > a large detour. > > Yonggang, does that sounds good for you? > Daniel, does that sounds good for you also? > > Regards, > Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-08 0:00 ` Pierrick Bouvier 2026-10-08 0:03 ` Pierrick Bouvier @ 2026-10-08 2:08 ` Yonggang Luo 2026-10-08 15:58 ` Pierrick Bouvier 2026-10-08 9:36 ` Daniel P. Berrangé 2 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-08 2:08 UTC (permalink / raw) To: Pierrick Bouvier Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Thu, Oct 8, 2026 at 8:00 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/7/2026 2:42 PM, Yonggang Luo wrote: > > On Thu, Oct 8, 2026 at 4:44 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> wrote: > >> > >> On 10/7/2026 4:48 AM, Yonggang Luo wrote: > >>> Change TypeInfo.is_available to the new TypeIsAvailable type, which > >>> takes a const TargetInfo *. Registration passes target_info(), so > >>> behavior is unchanged. object.h only forward-declares TargetInfo. > >>> > >>> Switch the existing users (raspi, raspi4b, ast27x0 evb and fc) and the > >>> generated machine parents to the matching target_is_<arch> helpers. > >>> > >>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > >>> --- > >>> hw/arm/aspeed_ast27x0-fc.c | 2 +- > >>> hw/arm/aspeed_ast27x0_evb.c | 4 ++-- > >>> hw/arm/raspi.c | 4 ++-- > >>> hw/arm/raspi4b.c | 2 +- > >>> hw/arm/virt.c | 4 ++-- > >>> hw/m68k/virt.c | 4 ++-- > >>> hw/or1k/virt.c | 2 +- > >>> include/qom/object.h | 12 +++++++++++- > >>> qom/object.c | 3 ++- > >>> 9 files changed, 24 insertions(+), 13 deletions(-) > >>> > >>> diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c > >>> index 73362b60d2a..8a7c6a116ac 100644 > >>> --- a/hw/arm/aspeed_ast27x0-fc.c > >>> +++ b/hw/arm/aspeed_ast27x0-fc.c > >>> @@ -234,7 +234,7 @@ static const TypeInfo ast2700fc_types[] = { > >>> .parent = TYPE_MACHINE, > >>> .class_init = ast2700fc_class_init, > >>> .instance_size = sizeof(Ast2700FCState), > >>> - .is_available = target_aarch64, > >>> + .is_available = target_is_aarch64, > >>> }, > >>> }; > >>> > >>> diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c > >>> index 460c9ff0d2e..02a8cff1d9d 100644 > >>> --- a/hw/arm/aspeed_ast27x0_evb.c > >>> +++ b/hw/arm/aspeed_ast27x0_evb.c > >>> @@ -75,13 +75,13 @@ static const TypeInfo aspeed_ast27x0_evb_types[] = { > >>> .name = MACHINE_TYPE_NAME("ast2700a1-evb"), > >>> .parent = TYPE_ASPEED_MACHINE, > >>> .class_init = aspeed_machine_ast2700a1_evb_class_init, > >>> - .is_available = target_aarch64, > >>> + .is_available = target_is_aarch64, > >>> }, > >>> { > >>> .name = MACHINE_TYPE_NAME("ast2700a2-evb"), > >>> .parent = TYPE_ASPEED_MACHINE, > >>> .class_init = aspeed_machine_ast2700a2_evb_class_init, > >>> - .is_available = target_aarch64, > >>> + .is_available = target_is_aarch64, > >>> } > >>> }; > >>> > >>> diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c > >>> index fadbacb2534..22b06c6ca22 100644 > >>> --- a/hw/arm/raspi.c > >>> +++ b/hw/arm/raspi.c > >>> @@ -403,12 +403,12 @@ static const TypeInfo raspi_machine_types[] = { > >>> .name = MACHINE_TYPE_NAME("raspi3ap"), > >>> .parent = TYPE_RASPI_MACHINE, > >>> .class_init = raspi3ap_machine_class_init, > >>> - .is_available = target_aarch64, > >>> + .is_available = target_is_aarch64, > >>> }, { > >>> .name = MACHINE_TYPE_NAME("raspi3b"), > >>> .parent = TYPE_RASPI_MACHINE, > >>> .class_init = raspi3b_machine_class_init, > >>> - .is_available = target_aarch64, > >>> + .is_available = target_is_aarch64, > >>> }, { > >>> .name = TYPE_RASPI_MACHINE, > >>> .parent = TYPE_RASPI_BASE_MACHINE, > >>> diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c > >>> index 566d64572db..a1dc477f25e 100644 > >>> --- a/hw/arm/raspi4b.c > >>> +++ b/hw/arm/raspi4b.c > >>> @@ -121,7 +121,7 @@ static const TypeInfo raspi4b_machine_type = { > >>> .parent = TYPE_RASPI_BASE_MACHINE, > >>> .instance_size = sizeof(Raspi4bMachineState), > >>> .class_init = raspi4b_machine_class_init, > >>> - .is_available = target_aarch64, > >>> + .is_available = target_is_aarch64, > >>> }; > >>> > >>> static void raspi4b_machine_register_type(void) > >>> diff --git a/hw/arm/virt.c b/hw/arm/virt.c > >>> index 9d192515d85..18160f7fad3 100644 > >>> --- a/hw/arm/virt.c > >>> +++ b/hw/arm/virt.c > >>> @@ -132,7 +132,7 @@ static void arm_virt_compat_default_set(MachineClass *mc) > >>> .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ > >>> .parent = TYPE_VIRT_MACHINE, \ > >>> .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ > >>> - .is_available = target_base_arm, \ > >>> + .is_available = target_is_base_arm, \ > >>> }; \ > >>> static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ > >>> { \ > >>> @@ -4430,7 +4430,7 @@ static const TypeInfo virt_machine_info = { > >>> { TYPE_HOTPLUG_HANDLER }, > >>> { } > >>> }, > >>> - .is_available = target_base_arm, > >>> + .is_available = target_is_base_arm, > >>> }; > >>> > >>> static void machvirt_machine_init(void) > >>> diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c > >>> index e52546e4fab..ad2a43ef3fb 100644 > >>> --- a/hw/m68k/virt.c > >>> +++ b/hw/m68k/virt.c > >>> @@ -327,7 +327,7 @@ static const TypeInfo virt_machine_info = { > >>> .parent = TYPE_MACHINE, > >>> .abstract = true, > >>> .class_init = virt_machine_class_init, > >>> - .is_available = target_m68k, > >>> + .is_available = target_is_m68k, > >>> }; > >>> > >>> static void virt_machine_register_types(void) > >>> @@ -355,7 +355,7 @@ type_init(virt_machine_register_types) > >>> .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \ > >>> .parent = MACHINE_TYPE_NAME("virt"), \ > >>> .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \ > >>> - .is_available = target_m68k, \ > >>> + .is_available = target_is_m68k, \ > >>> }; \ > >>> static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \ > >>> { \ > >>> diff --git a/hw/or1k/virt.c b/hw/or1k/virt.c > >>> index a3ff903839b..89fb786641f 100644 > >>> --- a/hw/or1k/virt.c > >>> +++ b/hw/or1k/virt.c > >>> @@ -559,7 +559,7 @@ static const TypeInfo or1ksim_machine_typeinfo = { > >>> .parent = TYPE_MACHINE, > >>> .class_init = openrisc_virt_machine_init, > >>> .instance_size = sizeof(OR1KVirtState), > >>> - .is_available = target_or1k, > >>> + .is_available = target_is_or1k, > >>> }; > >>> > >>> static void or1ksim_machine_init_register_types(void) > >>> diff --git a/include/qom/object.h b/include/qom/object.h > >>> index 4c0645817a5..7d52a15f6b8 100644 > >>> --- a/include/qom/object.h > >>> +++ b/include/qom/object.h > >>> @@ -17,6 +17,7 @@ > >>> #include "qapi/qapi-builtin-types.h" > >>> #include "qemu/module.h" > >>> > >>> +typedef struct TargetInfo TargetInfo; > >>> struct TypeImpl; > >>> typedef struct TypeImpl *Type; > >>> > >>> @@ -117,6 +118,15 @@ typedef void (ObjectUnparent)(Object *obj); > >>> */ > >>> typedef void (ObjectFree)(void *obj); > >>> > >>> +/** > >>> + * typedef TypeIsAvailable: > >>> + * @ti: TargetInfo to test. > >>> + * > >>> + * Returns whether a type is available for @ti. Typical implementations > >>> + * are target_is_*(). > >>> + */ > >>> +typedef bool (TypeIsAvailable)(const TargetInfo *ti); > >>> + > >>> #define OBJECT_CLASS_CAST_CACHE 4 > >>> > >>> /** > >>> @@ -498,7 +508,7 @@ struct TypeInfo > >>> void (*class_base_init)(ObjectClass *klass, const void *data); > >>> const void *class_data; > >>> > >>> - bool (*is_available)(void); > >>> + TypeIsAvailable *is_available; > >>> const InterfaceInfo *interfaces; > >>> }; > >>> > >>> diff --git a/qom/object.c b/qom/object.c > >>> index 96498f3d001..253b9562b41 100644 > >>> --- a/qom/object.c > >>> +++ b/qom/object.c > >>> @@ -15,6 +15,7 @@ > >>> #include "qom/compat-properties.h" > >>> #include "qom/object.h" > >>> #include "qom/object_interfaces.h" > >>> +#include "qemu/target-info.h" > >>> #include "qemu/cutils.h" > >>> #include "qemu/memalign.h" > >>> #include "qapi/visitor.h" > >>> @@ -167,7 +168,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info) > >>> abort(); > >>> } > >>> > >>> - if (info->is_available && !info->is_available()) { > >>> + if (info->is_available && !info->is_available(target_info())) { > >>> return NULL; > >>> } > >>> > >> > >> ``` > >> info->is_available(target_info()) > >> ``` > >> > >> or > >> > >> ``` > >> is_available() { > >> TargetInfo ti * = target_info(); > >> ... > >> } > >> ``` > >> > >> Are doing the exact same thing today. > >> > >> So what is the future goal requiring to introduce this? > > > > From Daniel P. Berrangé's > > requesthttps://lore.kernel.org/qemu-devel/apAszS1ewxM0Y1XU@redhat.com/ > > I forgot to mention that this is also pretty important for making > > introspection work, as we need to be able to say > > > > 'qemu-system --machine none -qmp ...' > > > > and connect to QMP to introspect the binary. Having to add a > > '--target <name>' into that mix is undesirable, as it creates > > a chicken & egg problem. You don't know what targets are built > > into qemu-system without introspecting it and you can't > > introspect it without selecting a target to introspect. > > > > From Pierrick's review > > https://lore.kernel.org/qemu-devel/557262df-b8e7-49b5-a245-ae46b8885b30@oss.qualcomm.com/So, > > for existing binary: -M virt works as before. > > > > For new multi binary: > > $ qemu-system -M virt: > > Multiple machines were found, select one among: > > - aarch64-virt > > - riscv64-virt > > > > Does it matches what you would expect? > > > > From Daniel's review > > https://lore.kernel.org/qemu-devel/aro93NuZBXYGbD33@redhat.com/ > > We already have 'QemuTargetInfo' struct which is used > > with 'query-target', that should also be used with the > > new 'query-targets' command. > > > > We need to add the 'endianness' field to QemuTargetInfo. > > > > I don't think that we need to report machines though. > > We already have 'query-machines' which gives much broader > > information on the machines. "MachineInfo" needs to > > gain > > > > "targets": ["SysEmuTarget"] > > > > to list which target(s) a machine can be used with. > > > > > > To achieve these, we needs add TypeInfo parameter to it so that we can do > > > > static void report_unsupported_machine_type(const char *name, Error **errp) > > { > > g_autoptr(GSList) machines = machine_class_get_list(true); > > g_autoptr(GString) targets = g_string_new(NULL); > > TargetInfoNode *node; > > GSList *el; > > > > error_setg(errp, "unsupported machine type: \"%s\" for target \"%s\"", > > name, target_name()); > > QLIST_FOREACH(node, target_info_list(), next) { > > for (el = machines; el; el = el->next) { > > MachineClass *mc = el->data; > > > > if ((!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) && > > object_class_get_is_available(OBJECT_CLASS(mc))(node->info)) { > > g_string_append_printf(targets, " %s\n", > > node->info->target_name); > > break; > > } > > } > > } > > if (targets->len) { > > error_append_hint(errp, "Available for targets:\n%s", targets->str); > > } > > } > > > > That is we can iterate on all target-list, and check if it's can be fitlered. > > > > Ok, I finally see where this is going. > > 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. */ static const TypeInfo target_machine_types[] = { { .name = TYPE_TARGET_BASE_ALPHA_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_alpha, }, { .name = TYPE_TARGET_BASE_ARM_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_arm, }, { .name = TYPE_TARGET_BASE_AVR_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_avr, }, { .name = TYPE_TARGET_BASE_HEXAGON_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_hexagon, }, { .name = TYPE_TARGET_BASE_HPPA_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_hppa, }, { .name = TYPE_TARGET_BASE_I386_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_i386, }, { .name = TYPE_TARGET_BASE_LOONGARCH_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_loongarch, }, { .name = TYPE_TARGET_BASE_M68K_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_m68k, }, { .name = TYPE_TARGET_BASE_MICROBLAZE_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_microblaze, }, { .name = TYPE_TARGET_BASE_MIPS_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_mips, }, { .name = TYPE_TARGET_BASE_NONE_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_none, }, { .name = TYPE_TARGET_BASE_OR1K_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_or1k, }, { .name = TYPE_TARGET_BASE_PPC_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_ppc, }, { .name = TYPE_TARGET_BASE_RISCV_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_riscv, }, { .name = TYPE_TARGET_BASE_RX_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_rx, }, { .name = TYPE_TARGET_BASE_S390X_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_s390x, }, { .name = TYPE_TARGET_BASE_SH4_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_sh4, }, { .name = TYPE_TARGET_BASE_SPARC_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_sparc, }, { .name = TYPE_TARGET_BASE_TRICORE_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_tricore, }, { .name = TYPE_TARGET_BASE_XTENSA_MACHINE, .parent = TYPE_MACHINE, .abstract = true, .is_available = target_is_base_xtensa, }, { .name = TYPE_TARGET_ALPHA_MACHINE, .parent = TYPE_TARGET_BASE_ALPHA_MACHINE, .abstract = true, .is_available = target_is_alpha, }, { .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, }, { .name = TYPE_TARGET_AVR_MACHINE, .parent = TYPE_TARGET_BASE_AVR_MACHINE, .abstract = true, .is_available = target_is_avr, }, { .name = TYPE_TARGET_HEXAGON_MACHINE, .parent = TYPE_TARGET_BASE_HEXAGON_MACHINE, .abstract = true, .is_available = target_is_hexagon, }, { .name = TYPE_TARGET_HPPA_MACHINE, .parent = TYPE_TARGET_BASE_HPPA_MACHINE, .abstract = true, .is_available = target_is_hppa, }, { .name = TYPE_TARGET_I386_MACHINE, .parent = TYPE_TARGET_BASE_I386_MACHINE, .abstract = true, .is_available = target_is_i386, }, { .name = TYPE_TARGET_X86_64_MACHINE, .parent = TYPE_TARGET_BASE_I386_MACHINE, .abstract = true, .is_available = target_is_x86_64, }, { .name = TYPE_TARGET_LOONGARCH64_MACHINE, .parent = TYPE_TARGET_BASE_LOONGARCH_MACHINE, .abstract = true, .is_available = target_is_loongarch64, }, { .name = TYPE_TARGET_M68K_MACHINE, .parent = TYPE_TARGET_BASE_M68K_MACHINE, .abstract = true, .is_available = target_is_m68k, }, { .name = TYPE_TARGET_MICROBLAZE_MACHINE, .parent = TYPE_TARGET_BASE_MICROBLAZE_MACHINE, .abstract = true, .is_available = target_is_microblaze, }, { .name = TYPE_TARGET_MIPS_MACHINE, .parent = TYPE_TARGET_BASE_MIPS_MACHINE, .abstract = true, .is_available = target_is_mips, }, { .name = TYPE_TARGET_MIPS64_MACHINE, .parent = TYPE_TARGET_BASE_MIPS_MACHINE, .abstract = true, .is_available = target_is_mips64, }, { .name = TYPE_TARGET_MIPS64EL_MACHINE, .parent = TYPE_TARGET_BASE_MIPS_MACHINE, .abstract = true, .is_available = target_is_mips64el, }, { .name = TYPE_TARGET_MIPSEL_MACHINE, .parent = TYPE_TARGET_BASE_MIPS_MACHINE, .abstract = true, .is_available = target_is_mipsel, }, { .name = TYPE_TARGET_NONE_MACHINE, .parent = TYPE_TARGET_BASE_NONE_MACHINE, .abstract = true, .is_available = target_is_none, }, { .name = TYPE_TARGET_OR1K_MACHINE, .parent = TYPE_TARGET_BASE_OR1K_MACHINE, .abstract = true, .is_available = target_is_or1k, }, { .name = TYPE_TARGET_PPC_MACHINE, .parent = TYPE_TARGET_BASE_PPC_MACHINE, .abstract = true, .is_available = target_is_ppc, }, { .name = TYPE_TARGET_PPC64_MACHINE, .parent = TYPE_TARGET_BASE_PPC_MACHINE, .abstract = true, .is_available = target_is_ppc64, }, { .name = TYPE_TARGET_RISCV32_MACHINE, .parent = TYPE_TARGET_BASE_RISCV_MACHINE, .abstract = true, .is_available = target_is_riscv32, }, { .name = TYPE_TARGET_RISCV64_MACHINE, .parent = TYPE_TARGET_BASE_RISCV_MACHINE, .abstract = true, .is_available = target_is_riscv64, }, { .name = TYPE_TARGET_RX_MACHINE, .parent = TYPE_TARGET_BASE_RX_MACHINE, .abstract = true, .is_available = target_is_rx, }, { .name = TYPE_TARGET_S390X_MACHINE, .parent = TYPE_TARGET_BASE_S390X_MACHINE, .abstract = true, .is_available = target_is_s390x, }, { .name = TYPE_TARGET_SH4_MACHINE, .parent = TYPE_TARGET_BASE_SH4_MACHINE, .abstract = true, .is_available = target_is_sh4, }, { .name = TYPE_TARGET_SH4EB_MACHINE, .parent = TYPE_TARGET_BASE_SH4_MACHINE, .abstract = true, .is_available = target_is_sh4eb, }, { .name = TYPE_TARGET_SPARC_MACHINE, .parent = TYPE_TARGET_BASE_SPARC_MACHINE, .abstract = true, .is_available = target_is_sparc, }, { .name = TYPE_TARGET_SPARC64_MACHINE, .parent = TYPE_TARGET_BASE_SPARC_MACHINE, .abstract = true, .is_available = target_is_sparc64, }, { .name = TYPE_TARGET_TRICORE_MACHINE, .parent = TYPE_TARGET_BASE_TRICORE_MACHINE, .abstract = true, .is_available = target_is_tricore, }, { .name = TYPE_TARGET_XTENSA_MACHINE, .parent = TYPE_TARGET_BASE_XTENSA_MACHINE, .abstract = true, .is_available = target_is_xtensa, }, { .name = TYPE_TARGET_XTENSAEB_MACHINE, .parent = TYPE_TARGET_BASE_XTENSA_MACHINE, .abstract = true, .is_available = target_is_xtensaeb, }, }; 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 > > 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; > ``` 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*). 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. > > @Daniel, IIUC, this is exactly the approach you proposed a few weeks > ago, just before I got frustrated and lost my patience against you. I > think it's more clear for me where you wanted to go. Sorry it took such > a large detour. > > Yonggang, does that sounds good for you? > Daniel, does that sounds good for you also? > > Regards, > Pierrick -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-08 2:08 ` Yonggang Luo @ 2026-10-08 15:58 ` Pierrick Bouvier 0 siblings, 0 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-08 15:58 UTC (permalink / raw) To: luoyonggang Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny 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 ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-08 0:00 ` Pierrick Bouvier 2026-10-08 0:03 ` Pierrick Bouvier 2026-10-08 2:08 ` Yonggang Luo @ 2026-10-08 9:36 ` Daniel P. Berrangé 2026-10-08 9:56 ` Yonggang Luo 2 siblings, 1 reply; 62+ messages in thread From: Daniel P. Berrangé @ 2026-10-08 9:36 UTC (permalink / raw) To: Pierrick Bouvier Cc: luoyonggang, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Wed, Oct 07, 2026 at 05:00:06PM -0700, Pierrick Bouvier wrote: > On 10/7/2026 2:42 PM, Yonggang Luo wrote: > > On Thu, Oct 8, 2026 at 4:44 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> wrote: > >> > >> On 10/7/2026 4:48 AM, Yonggang Luo wrote: > >>> Change TypeInfo.is_available to the new TypeIsAvailable type, which > >>> takes a const TargetInfo *. Registration passes target_info(), so > >>> behavior is unchanged. object.h only forward-declares TargetInfo. > >>> > >>> Switch the existing users (raspi, raspi4b, ast27x0 evb and fc) and the > >>> generated machine parents to the matching target_is_<arch> helpers. > >>> > >>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > >>> --- > >>> hw/arm/aspeed_ast27x0-fc.c | 2 +- > >>> hw/arm/aspeed_ast27x0_evb.c | 4 ++-- > >>> hw/arm/raspi.c | 4 ++-- > >>> hw/arm/raspi4b.c | 2 +- > >>> hw/arm/virt.c | 4 ++-- > >>> hw/m68k/virt.c | 4 ++-- > >>> hw/or1k/virt.c | 2 +- > >>> include/qom/object.h | 12 +++++++++++- > >>> qom/object.c | 3 ++- > >>> 9 files changed, 24 insertions(+), 13 deletions(-) snip > >>> @@ -167,7 +168,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info) > >>> abort(); > >>> } > >>> > >>> - if (info->is_available && !info->is_available()) { > >>> + if (info->is_available && !info->is_available(target_info())) { > >>> return NULL; > >>> } > >>> > >> > >> ``` > >> info->is_available(target_info()) > >> ``` > >> > >> or > >> > >> ``` > >> is_available() { > >> TargetInfo ti * = target_info(); > >> ... > >> } > >> ``` > >> > >> Are doing the exact same thing today. > >> > >> So what is the future goal requiring to introduce this? > > > > From Daniel P. Berrangé's > > requesthttps://lore.kernel.org/qemu-devel/apAszS1ewxM0Y1XU@redhat.com/ > > I forgot to mention that this is also pretty important for making > > introspection work, as we need to be able to say > > > > 'qemu-system --machine none -qmp ...' > > > > and connect to QMP to introspect the binary. Having to add a > > '--target <name>' into that mix is undesirable, as it creates > > a chicken & egg problem. You don't know what targets are built > > into qemu-system without introspecting it and you can't > > introspect it without selecting a target to introspect. > > > > From Pierrick's review > > https://lore.kernel.org/qemu-devel/557262df-b8e7-49b5-a245-ae46b8885b30@oss.qualcomm.com/So, > > for existing binary: -M virt works as before. > > > > For new multi binary: > > $ qemu-system -M virt: > > Multiple machines were found, select one among: > > - aarch64-virt > > - riscv64-virt > > > > Does it matches what you would expect? > > > > From Daniel's review > > https://lore.kernel.org/qemu-devel/aro93NuZBXYGbD33@redhat.com/ > > We already have 'QemuTargetInfo' struct which is used > > with 'query-target', that should also be used with the > > new 'query-targets' command. > > > > We need to add the 'endianness' field to QemuTargetInfo. > > > > I don't think that we need to report machines though. > > We already have 'query-machines' which gives much broader > > information on the machines. "MachineInfo" needs to > > gain > > > > "targets": ["SysEmuTarget"] > > > > to list which target(s) a machine can be used with. > > > > > > To achieve these, we needs add TypeInfo parameter to it so that we can do > > > > static void report_unsupported_machine_type(const char *name, Error **errp) > > { > > g_autoptr(GSList) machines = machine_class_get_list(true); > > g_autoptr(GString) targets = g_string_new(NULL); > > TargetInfoNode *node; > > GSList *el; > > > > error_setg(errp, "unsupported machine type: \"%s\" for target \"%s\"", > > name, target_name()); > > QLIST_FOREACH(node, target_info_list(), next) { > > for (el = machines; el; el = el->next) { > > MachineClass *mc = el->data; > > > > if ((!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) && > > object_class_get_is_available(OBJECT_CLASS(mc))(node->info)) { > > g_string_append_printf(targets, " %s\n", > > node->info->target_name); > > break; > > } > > } > > } > > if (targets->len) { > > error_append_hint(errp, "Available for targets:\n%s", targets->str); > > } > > } > > > > That is we can iterate on all target-list, and check if it's can be fitlered. > > > > Ok, I finally see where this is going. > > So, based on all the previous conversations, we agreed to have a > qemu-system binary with all the QOM types available (for all targets). ack. > I personally think that if we go this way, we should not have any > -target option, and even less a -target none option. If we don't have a compelling need for -target to exist now, then dropping it as a concept is good. > 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? > > It's what we did in the past > (https://gitlab.com/qemu-project/qemu/-/commit/5de9216064d32eaac125dac4de1878486c16d73e), > 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; > ``` > > @Daniel, IIUC, this is exactly the approach you proposed a few weeks > ago, just before I got frustrated and lost my patience against you. I > think it's more clear for me where you wanted to go. Sorry it took such > a large detour. Not a problem. We were coming at the debate with different ideas of where we were heading, so talking past each other at times. > > Yonggang, does that sounds good for you? > Daniel, does that sounds good for you also? Works for me. With regards, Daniel -- |: https://berrange.com ~~ https://hachyderm.io/@berrange :| |: https://libvirt.org ~~ https://entangle-photo.org :| |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :| ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-08 9:36 ` Daniel P. Berrangé @ 2026-10-08 9:56 ` Yonggang Luo 2026-10-08 16:01 ` Pierrick Bouvier 0 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-08 9:56 UTC (permalink / raw) To: Daniel P. Berrangé Cc: Pierrick Bouvier, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Thu, Oct 8, 2026 at 5:36 PM Daniel P. Berrangé <berrange@redhat.com> wrote: > > On Wed, Oct 07, 2026 at 05:00:06PM -0700, Pierrick Bouvier wrote: > > On 10/7/2026 2:42 PM, Yonggang Luo wrote: > > > On Thu, Oct 8, 2026 at 4:44 AM Pierrick Bouvier > > > <pierrick.bouvier@oss.qualcomm.com> wrote: > > >> > > >> On 10/7/2026 4:48 AM, Yonggang Luo wrote: > > >>> Change TypeInfo.is_available to the new TypeIsAvailable type, which > > >>> takes a const TargetInfo *. Registration passes target_info(), so > > >>> behavior is unchanged. object.h only forward-declares TargetInfo. > > >>> > > >>> Switch the existing users (raspi, raspi4b, ast27x0 evb and fc) and the > > >>> generated machine parents to the matching target_is_<arch> helpers. > > >>> > > >>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com> > > >>> --- > > >>> hw/arm/aspeed_ast27x0-fc.c | 2 +- > > >>> hw/arm/aspeed_ast27x0_evb.c | 4 ++-- > > >>> hw/arm/raspi.c | 4 ++-- > > >>> hw/arm/raspi4b.c | 2 +- > > >>> hw/arm/virt.c | 4 ++-- > > >>> hw/m68k/virt.c | 4 ++-- > > >>> hw/or1k/virt.c | 2 +- > > >>> include/qom/object.h | 12 +++++++++++- > > >>> qom/object.c | 3 ++- > > >>> 9 files changed, 24 insertions(+), 13 deletions(-) > > snip > > > >>> @@ -167,7 +168,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info) > > >>> abort(); > > >>> } > > >>> > > >>> - if (info->is_available && !info->is_available()) { > > >>> + if (info->is_available && !info->is_available(target_info())) { > > >>> return NULL; > > >>> } > > >>> > > >> > > >> ``` > > >> info->is_available(target_info()) > > >> ``` > > >> > > >> or > > >> > > >> ``` > > >> is_available() { > > >> TargetInfo ti * = target_info(); > > >> ... > > >> } > > >> ``` > > >> > > >> Are doing the exact same thing today. > > >> > > >> So what is the future goal requiring to introduce this? > > > > > > From Daniel P. Berrangé's > > > requesthttps://lore.kernel.org/qemu-devel/apAszS1ewxM0Y1XU@redhat.com/ > > > I forgot to mention that this is also pretty important for making > > > introspection work, as we need to be able to say > > > > > > 'qemu-system --machine none -qmp ...' > > > > > > and connect to QMP to introspect the binary. Having to add a > > > '--target <name>' into that mix is undesirable, as it creates > > > a chicken & egg problem. You don't know what targets are built > > > into qemu-system without introspecting it and you can't > > > introspect it without selecting a target to introspect. > > > > > > From Pierrick's review > > > https://lore.kernel.org/qemu-devel/557262df-b8e7-49b5-a245-ae46b8885b30@oss.qualcomm.com/So, > > > for existing binary: -M virt works as before. > > > > > > For new multi binary: > > > $ qemu-system -M virt: > > > Multiple machines were found, select one among: > > > - aarch64-virt > > > - riscv64-virt > > > > > > Does it matches what you would expect? > > > > > > From Daniel's review > > > https://lore.kernel.org/qemu-devel/aro93NuZBXYGbD33@redhat.com/ > > > We already have 'QemuTargetInfo' struct which is used > > > with 'query-target', that should also be used with the > > > new 'query-targets' command. > > > > > > We need to add the 'endianness' field to QemuTargetInfo. > > > > > > I don't think that we need to report machines though. > > > We already have 'query-machines' which gives much broader > > > information on the machines. "MachineInfo" needs to > > > gain > > > > > > "targets": ["SysEmuTarget"] > > > > > > to list which target(s) a machine can be used with. > > > > > > > > > To achieve these, we needs add TypeInfo parameter to it so that we can do > > > > > > static void report_unsupported_machine_type(const char *name, Error **errp) > > > { > > > g_autoptr(GSList) machines = machine_class_get_list(true); > > > g_autoptr(GString) targets = g_string_new(NULL); > > > TargetInfoNode *node; > > > GSList *el; > > > > > > error_setg(errp, "unsupported machine type: \"%s\" for target \"%s\"", > > > name, target_name()); > > > QLIST_FOREACH(node, target_info_list(), next) { > > > for (el = machines; el; el = el->next) { > > > MachineClass *mc = el->data; > > > > > > if ((!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) && > > > object_class_get_is_available(OBJECT_CLASS(mc))(node->info)) { > > > g_string_append_printf(targets, " %s\n", > > > node->info->target_name); > > > break; > > > } > > > } > > > } > > > if (targets->len) { > > > error_append_hint(errp, "Available for targets:\n%s", targets->str); > > > } > > > } > > > > > > That is we can iterate on all target-list, and check if it's can be fitlered. > > > > > > > Ok, I finally see where this is going. > > > > So, based on all the previous conversations, we agreed to have a > > qemu-system binary with all the QOM types available (for all targets). > > ack. > > > I personally think that if we go this way, we should not have any > > -target option, and even less a -target none option. > > If we don't have a compelling need for -target to exist now, then > dropping it as a concept is good. > > > 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? > > > > It's what we did in the past > > (https://gitlab.com/qemu-project/qemu/-/commit/5de9216064d32eaac125dac4de1878486c16d73e), > > 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; To be explicit state what, I give you a pseudo code to compute machine->targets from TypeInfo::is_available(TargetInfo*) let targets=0 foreach ti of TargetInfo list: if (machine::TypeImpl::is_avaible(ti)) targets |= 1 << ti->target_arch fi endif So they basically have equivalent effect, and is_available will handle other code-needed condition properly such as CPU/AccelClass. not restrict to targets, we can also attach the KConfig into TargetInfo, so is_available(TargetInfo*) also works for Kconfig. that's why I insist this way, it's solved all the issues around. so machine->targets = EMU_TARGET_X | EMU_TARGET_Y; is a good idea, and it can be implemented with TypeInfo::is_available(TargetInfo*) without much burden. and targets can be saved into a (machine or TypeImpl) for fast access when needed, we can compute it when the program starts. > > ``` > > > > @Daniel, IIUC, this is exactly the approach you proposed a few weeks > > ago, just before I got frustrated and lost my patience against you. I > > think it's more clear for me where you wanted to go. Sorry it took such > > a large detour. > > Not a problem. We were coming at the debate with different ideas of > where we were heading, so talking past each other at times. > > > > > Yonggang, does that sounds good for you? > > Daniel, does that sounds good for you also? > > Works for me. > > With regards, > Daniel > -- > |: https://berrange.com ~~ https://hachyderm.io/@berrange :| > |: https://libvirt.org ~~ https://entangle-photo.org :| > |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :| > -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-08 9:56 ` Yonggang Luo @ 2026-10-08 16:01 ` Pierrick Bouvier 2026-10-08 17:04 ` Yonggang Luo 0 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-08 16:01 UTC (permalink / raw) To: luoyonggang, Daniel P. Berrangé Cc: qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/8/2026 2:56 AM, Yonggang Luo wrote: >>> 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; > > To be explicit state what, I give you a pseudo code to compute > machine->targets from TypeInfo::is_available(TargetInfo*) > let targets=0 > foreach ti of TargetInfo list: > if (machine::TypeImpl::is_avaible(ti)) > targets |= 1 << ti->target_arch > fi > endif > So they basically have equivalent effect, and is_available will handle > other code-needed condition properly such as > CPU/AccelClass. not restrict to targets, we can also attach the > KConfig into TargetInfo, so is_available(TargetInfo*) > also works for Kconfig. that's why I insist this way, it's solved all > the issues around. > > so machine->targets = EMU_TARGET_X | EMU_TARGET_Y; is a good idea, > and it can be implemented with TypeInfo::is_available(TargetInfo*) > without much burden. and targets can be saved into a (machine or > TypeImpl) for fast access when needed, we can compute it > when the program starts. > In what we described, there is no need to keep any kind of callback, targets field is sufficient to filter any type declaratively. For the KConfig related types, I would really be keen to leave that available for now, and add a proper error message later. Regards, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-08 16:01 ` Pierrick Bouvier @ 2026-10-08 17:04 ` Yonggang Luo 2026-10-08 18:26 ` Pierrick Bouvier 0 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-08 17:04 UTC (permalink / raw) To: Pierrick Bouvier Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Fri, Oct 9, 2026 at 12:01 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/8/2026 2:56 AM, Yonggang Luo wrote: > >>> 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; > > > > To be explicit state what, I give you a pseudo code to compute > > machine->targets from TypeInfo::is_available(TargetInfo*) > > let targets=0 > > foreach ti of TargetInfo list: > > if (machine::TypeImpl::is_avaible(ti)) > > targets |= 1 << ti->target_arch > > fi > > endif > > So they basically have equivalent effect, and is_available will handle > > other code-needed condition properly such as > > CPU/AccelClass. not restrict to targets, we can also attach the > > KConfig into TargetInfo, so is_available(TargetInfo*) > > also works for Kconfig. that's why I insist this way, it's solved all > > the issues around. > > > > so machine->targets = EMU_TARGET_X | EMU_TARGET_Y; is a good idea, > > and it can be implemented with TypeInfo::is_available(TargetInfo*) > > without much burden. and targets can be saved into a (machine or > > TypeImpl) for fast access when needed, we can compute it > > when the program starts. > > > > In what we described, there is no need to keep any kind of callback, > targets field is sufficient to filter any type declaratively. > > For the KConfig related types, I would really be keen to leave that > available for now, and add a proper error message later. Thanks, much clearer now, I was working for full KConfig related types support because I am trying to keep qemu-system-$arch to be a symlink to qemu-system which will still work without breaking anything. If we do not keep this then I machine::targets or TypeInfo::targets would be the best solution, I think TypeInfo::targets is better, and copy it into TypeImpl::targets. and give a API to retrieve it, for example: uint64_t *object_class_get_targets(ObjectClass *klass); Add "targets" struct members as TypeInfo::targets and TypeImpl::targets, and copy from TypeInfo into TypeImpl for later access with object_class_get_targets Then we can use it for filtering machines and cpus without burden. How to dealt with https://lore.kernel.org/qemu-devel/20261007-rv-dedup-v2-6-8a2f0f296a7f@rev.ng/ It's using is_available. Maybe all using the way like Subject: [PATCH v2 07/18] target/riscv: Runtime register MAX and BARE CPUs https://lore.kernel.org/qemu-devel/20261007-rv-dedup-v2-7-8a2f0f296a7f@rev.ng/ > > Regards, > Pierrick -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-08 17:04 ` Yonggang Luo @ 2026-10-08 18:26 ` Pierrick Bouvier 2026-10-08 18:33 ` Yonggang Luo 0 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-08 18:26 UTC (permalink / raw) To: luoyonggang Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/8/2026 10:04 AM, Yonggang Luo wrote: > On Fri, Oct 9, 2026 at 12:01 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> wrote: >> >> On 10/8/2026 2:56 AM, Yonggang Luo wrote: >>>>> 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; >>> >>> To be explicit state what, I give you a pseudo code to compute >>> machine->targets from TypeInfo::is_available(TargetInfo*) >>> let targets=0 >>> foreach ti of TargetInfo list: >>> if (machine::TypeImpl::is_avaible(ti)) >>> targets |= 1 << ti->target_arch >>> fi >>> endif >>> So they basically have equivalent effect, and is_available will handle >>> other code-needed condition properly such as >>> CPU/AccelClass. not restrict to targets, we can also attach the >>> KConfig into TargetInfo, so is_available(TargetInfo*) >>> also works for Kconfig. that's why I insist this way, it's solved all >>> the issues around. >>> >>> so machine->targets = EMU_TARGET_X | EMU_TARGET_Y; is a good idea, >>> and it can be implemented with TypeInfo::is_available(TargetInfo*) >>> without much burden. and targets can be saved into a (machine or >>> TypeImpl) for fast access when needed, we can compute it >>> when the program starts. >>> >> >> In what we described, there is no need to keep any kind of callback, >> targets field is sufficient to filter any type declaratively. >> >> For the KConfig related types, I would really be keen to leave that >> available for now, and add a proper error message later. > > Thanks, much clearer now, I was working for full KConfig related types support > because I am trying to keep qemu-system-$arch to be a symlink to qemu-system > which will still work without breaking anything. If we do not keep this then > I machine::targets or TypeInfo::targets would be the best solution, I think > TypeInfo::targets is better, and copy it into TypeImpl::targets. and give a API > to retrieve it, for example: > uint64_t *object_class_get_targets(ObjectClass *klass); > We can exclude the goal to replace existing binaries with a symlink for now. Please do not add this to TypeInfo, but to MachineClass instead, as explained in previous email. If you want to reduce upcoming frustration, I would really recommend you stick to this, and to a single machine to start. So we can validate the series, review it, and then you can iterate. > Add "targets" struct members as TypeInfo::targets and TypeImpl::targets, and > copy from TypeInfo into TypeImpl for later access with > object_class_get_targets > Then we can use it for filtering machines and cpus without burden. > > How to dealt with > https://lore.kernel.org/qemu-devel/20261007-rv-dedup-v2-6-8a2f0f296a7f@rev.ng/ > > It's using is_available. > .targets field can be conditioned by ifdef for config vs user, since what we have everything needed in build system allows to duplicate objects between user and system. #ifdef CONFIG_USER_ONLY .targets = ... #else .targets = ... #endif If that's not enough, it means the type has to be duplicated in some ways to resolve ambiguity (especially for 32 vs 64 bits variants). > Maybe all using the way like > Subject: [PATCH v2 07/18] target/riscv: Runtime register MAX and BARE CPUs > https://lore.kernel.org/qemu-devel/20261007-rv-dedup-v2-7-8a2f0f296a7f@rev.ng/ I would invite you to focus on a *single* machine first. See how to declare it, and how to query which target it supports. Then we can see what works/doesn't work, and (in a future series) we can do the same thing for cpus. You'll see that this iterative approach works much better than sending huge series. You have my word I'll be reactive and present to help continue this effort. Regards, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-08 18:26 ` Pierrick Bouvier @ 2026-10-08 18:33 ` Yonggang Luo 2026-10-08 18:40 ` Pierrick Bouvier 0 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-08 18:33 UTC (permalink / raw) To: Pierrick Bouvier Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Fri, Oct 9, 2026 at 2:27 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/8/2026 10:04 AM, Yonggang Luo wrote: > > On Fri, Oct 9, 2026 at 12:01 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> wrote: > >> > >> On 10/8/2026 2:56 AM, Yonggang Luo wrote: > >>>>> 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; > >>> > >>> To be explicit state what, I give you a pseudo code to compute > >>> machine->targets from TypeInfo::is_available(TargetInfo*) > >>> let targets=0 > >>> foreach ti of TargetInfo list: > >>> if (machine::TypeImpl::is_avaible(ti)) > >>> targets |= 1 << ti->target_arch > >>> fi > >>> endif > >>> So they basically have equivalent effect, and is_available will handle > >>> other code-needed condition properly such as > >>> CPU/AccelClass. not restrict to targets, we can also attach the > >>> KConfig into TargetInfo, so is_available(TargetInfo*) > >>> also works for Kconfig. that's why I insist this way, it's solved all > >>> the issues around. > >>> > >>> so machine->targets = EMU_TARGET_X | EMU_TARGET_Y; is a good idea, > >>> and it can be implemented with TypeInfo::is_available(TargetInfo*) > >>> without much burden. and targets can be saved into a (machine or > >>> TypeImpl) for fast access when needed, we can compute it > >>> when the program starts. > >>> > >> > >> In what we described, there is no need to keep any kind of callback, > >> targets field is sufficient to filter any type declaratively. > >> > >> For the KConfig related types, I would really be keen to leave that > >> available for now, and add a proper error message later. > > > > Thanks, much clearer now, I was working for full KConfig related types support > > because I am trying to keep qemu-system-$arch to be a symlink to qemu-system > > which will still work without breaking anything. If we do not keep this then > > I machine::targets or TypeInfo::targets would be the best solution, I think > > TypeInfo::targets is better, and copy it into TypeImpl::targets. and give a API > > to retrieve it, for example: > > uint64_t *object_class_get_targets(ObjectClass *klass); > > > > We can exclude the goal to replace existing binaries with a symlink for now. > > Please do not add this to TypeInfo, but to MachineClass instead, as > explained in previous email. I didn't see any simple way to do this, and don't know how, I am sorry. MachineClass init procedure is scattered, how would that be? I am afraid I am not able to get this done. If you can give some prepare work would be appreciated > If you want to reduce upcoming frustration, I would really recommend you > stick to this, and to a single machine to start. So we can validate the > series, review it, and then you can iterate. > > Add "targets" struct members as TypeInfo::targets and > TypeImpl::targets, and > > copy from TypeInfo into TypeImpl for later access with > > object_class_get_targets > > Then we can use it for filtering machines and cpus without burden. > > > > How to dealt with > > https://lore.kernel.org/qemu-devel/20261007-rv-dedup-v2-6-8a2f0f296a7f@rev.ng/ > > > > It's using is_available. > > > > .targets field can be conditioned by ifdef for config vs user, since > what we have everything needed in build system allows to duplicate > objects between user and system. > > #ifdef CONFIG_USER_ONLY > .targets = ... > #else > .targets = ... > #endif > > If that's not enough, it means the type has to be duplicated in some > ways to resolve ambiguity (especially for 32 vs 64 bits variants). > > > Maybe all using the way like > > Subject: [PATCH v2 07/18] target/riscv: Runtime register MAX and BARE CPUs > > https://lore.kernel.org/qemu-devel/20261007-rv-dedup-v2-7-8a2f0f296a7f@rev.ng/ > > I would invite you to focus on a *single* machine first. See how to > declare it, and how to query which target it supports. Then we can see > what works/doesn't work, and (in a future series) we can do the same > thing for cpus. > > You'll see that this iterative approach works much better than sending > huge series. You have my word I'll be reactive and present to help > continue this effort. > > Regards, > Pierrick -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 8/8] qom: pass TargetInfo to is_available for later use 2026-10-08 18:33 ` Yonggang Luo @ 2026-10-08 18:40 ` Pierrick Bouvier 0 siblings, 0 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-08 18:40 UTC (permalink / raw) To: luoyonggang Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/8/2026 11:33 AM, Yonggang Luo wrote: > On Fri, Oct 9, 2026 at 2:27 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> wrote: >> >> On 10/8/2026 10:04 AM, Yonggang Luo wrote: >>> On Fri, Oct 9, 2026 at 12:01 AM Pierrick Bouvier >>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>> >>>> On 10/8/2026 2:56 AM, Yonggang Luo wrote: >>>>>>> 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; >>>>> >>>>> To be explicit state what, I give you a pseudo code to compute >>>>> machine->targets from TypeInfo::is_available(TargetInfo*) >>>>> let targets=0 >>>>> foreach ti of TargetInfo list: >>>>> if (machine::TypeImpl::is_avaible(ti)) >>>>> targets |= 1 << ti->target_arch >>>>> fi >>>>> endif >>>>> So they basically have equivalent effect, and is_available will handle >>>>> other code-needed condition properly such as >>>>> CPU/AccelClass. not restrict to targets, we can also attach the >>>>> KConfig into TargetInfo, so is_available(TargetInfo*) >>>>> also works for Kconfig. that's why I insist this way, it's solved all >>>>> the issues around. >>>>> >>>>> so machine->targets = EMU_TARGET_X | EMU_TARGET_Y; is a good idea, >>>>> and it can be implemented with TypeInfo::is_available(TargetInfo*) >>>>> without much burden. and targets can be saved into a (machine or >>>>> TypeImpl) for fast access when needed, we can compute it >>>>> when the program starts. >>>>> >>>> >>>> In what we described, there is no need to keep any kind of callback, >>>> targets field is sufficient to filter any type declaratively. >>>> >>>> For the KConfig related types, I would really be keen to leave that >>>> available for now, and add a proper error message later. >>> >>> Thanks, much clearer now, I was working for full KConfig related types support >>> because I am trying to keep qemu-system-$arch to be a symlink to qemu-system >>> which will still work without breaking anything. If we do not keep this then >>> I machine::targets or TypeInfo::targets would be the best solution, I think >>> TypeInfo::targets is better, and copy it into TypeImpl::targets. and give a API >>> to retrieve it, for example: >>> uint64_t *object_class_get_targets(ObjectClass *klass); >>> >> >> We can exclude the goal to replace existing binaries with a symlink for now. >> >> Please do not add this to TypeInfo, but to MachineClass instead, as >> explained in previous email. > > I didn't see any simple way to do this, and don't know how, I am sorry. > MachineClass init procedure is scattered, how would that be? I am > afraid I am not > able to get this done. If you can give some prepare work would be appreciated > You can take a look at "git grep mc->desc". That's where you want to set targets. Also see MachineClass::desc, to see where to declare the field. There might be some machine classes that lack a class_init function, and thus will require to introduce it. If you find any occurrence that is not easy to solve, let me know, I'll help on it. >> If you want to reduce upcoming frustration, I would really recommend you >> stick to this, and to a single machine to start. So we can validate the >> series, review it, and then you can iterate. >> > Add "targets" struct members as TypeInfo::targets and >> TypeImpl::targets, and >>> copy from TypeInfo into TypeImpl for later access with >>> object_class_get_targets >>> Then we can use it for filtering machines and cpus without burden. >>> >>> How to dealt with >>> https://lore.kernel.org/qemu-devel/20261007-rv-dedup-v2-6-8a2f0f296a7f@rev.ng/ >>> >>> It's using is_available. >>> >> >> .targets field can be conditioned by ifdef for config vs user, since >> what we have everything needed in build system allows to duplicate >> objects between user and system. >> >> #ifdef CONFIG_USER_ONLY >> .targets = ... >> #else >> .targets = ... >> #endif >> >> If that's not enough, it means the type has to be duplicated in some >> ways to resolve ambiguity (especially for 32 vs 64 bits variants). >> >>> Maybe all using the way like >>> Subject: [PATCH v2 07/18] target/riscv: Runtime register MAX and BARE CPUs >>> https://lore.kernel.org/qemu-devel/20261007-rv-dedup-v2-7-8a2f0f296a7f@rev.ng/ >> >> I would invite you to focus on a *single* machine first. See how to >> declare it, and how to query which target it supports. Then we can see >> what works/doesn't work, and (in a future series) we can do the same >> thing for cpus. >> >> You'll see that this iterative approach works much better than sending >> huge series. You have my word I'll be reactive and present to help >> continue this effort. >> >> Regards, >> Pierrick > > > ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-07 11:47 [PATCH 0/8] qom: pass TargetInfo to the is_available callback Yonggang Luo ` (7 preceding siblings ...) 2026-10-07 11:48 ` [PATCH 8/8] qom: pass TargetInfo to is_available for later use Yonggang Luo @ 2026-10-07 20:25 ` Pierrick Bouvier 2026-10-08 9:42 ` Daniel P. Berrangé 2026-10-07 20:46 ` Pierrick Bouvier 9 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-07 20:25 UTC (permalink / raw) To: Yonggang Luo, qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny 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/ar_coT44h5-zJPVV@redhat.com/ 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. > It moves target_info() to a shared location so object.c can call it when > checking machine availability. The series also replaces QOM-based target-info > registration with a constructor list and passes TargetInfo to the > is_available callback. > > Target metadata and architecture checks are generated from the configured > targets, there is too much arch to write biiolperate code. doing this for easier > Add TargetInfo* to is_available > > The target-info API and implementation are shared, rather than compiled > separately for every target. > > This series removes the per-target source files "configs/targets/*.c". > Their target-specific parameters are collected in a generated > target-info-def.c for each softmmu target. This lays the groundwork for > QEMU system builds in which target-info-def.c is the only target-specific > source file compiled for each target. Using the same filename lets > meson.build handle these definitions uniformly. > > The series adds unit-test coverage for target info and multi-target builds. > > Pierrick Bouvier (2): > configs/targets: remove target info definitions > target-info: rename target-info-stub.c in target-info-def.c > > Yonggang Luo (6): > target-info: rename target-info-impl.h to target-info-def.h > target-info: replace QOM registration with a constructor list > tests/unit: add target-info coverage for multi-target builds > meson: load all target .mak files into target_mak_all > target-info: Replace handwritten architecture checks with generated > code > qom: pass TargetInfo to is_available for later use > > MAINTAINERS | 2 +- > configs/targets/aarch64-softmmu.c | 25 ------ > configs/targets/arm-softmmu.c | 25 ------ > configs/targets/meson.build | 6 -- > configs/targets/riscv32-softmmu.c | 24 ----- > configs/targets/riscv64-softmmu.c | 24 ----- > hw/arm/aspeed_ast27x0-fc.c | 2 +- > hw/arm/aspeed_ast27x0_evb.c | 4 +- > hw/arm/raspi.c | 4 +- > hw/arm/raspi4b.c | 2 +- > hw/arm/virt.c | 4 +- > hw/m68k/virt.c | 4 +- > hw/or1k/virt.c | 2 +- > include/hw/core/cpu.h | 2 +- > include/qemu/module.h | 1 - > include/qemu/target-info-def.h | 88 ++++++++++++++++++ > include/qemu/target-info-impl.h | 42 --------- > include/qemu/target-info-init.h | 53 ----------- > include/qemu/target-info-qom.h | 31 ------- > include/qemu/target-info.h | 87 ++++-------------- > include/qom/object.h | 12 ++- > meson.build | 52 ++++++++--- > page-vary-common.c | 2 +- > page-vary-system.c | 2 +- > qom/object.c | 3 +- > scripts/gen-target-info.py | 99 ++++++++++++++++++++ > system/vl.c | 4 - > target-info-stub.c => target-info-def.c | 3 +- > target-info-qom.c | 60 ------------- > target-info.c | 115 ++++++++++++------------ > tests/qtest/fuzz/fuzz.c | 3 - > tests/unit/meson.build | 4 + > tests/unit/test-multi-target.c | 12 +-- > tests/unit/test-target-info.c | 38 ++++++++ > 34 files changed, 379 insertions(+), 462 deletions(-) > delete mode 100644 configs/targets/aarch64-softmmu.c > delete mode 100644 configs/targets/arm-softmmu.c > delete mode 100644 configs/targets/meson.build > delete mode 100644 configs/targets/riscv32-softmmu.c > delete mode 100644 configs/targets/riscv64-softmmu.c > create mode 100644 include/qemu/target-info-def.h > delete mode 100644 include/qemu/target-info-impl.h > delete mode 100644 include/qemu/target-info-init.h > delete mode 100644 include/qemu/target-info-qom.h > create mode 100644 scripts/gen-target-info.py > rename target-info-stub.c => target-info-def.c (94%) > delete mode 100644 target-info-qom.c > create mode 100644 tests/unit/test-target-info.c > ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-07 20:25 ` [PATCH 0/8] qom: pass TargetInfo to the is_available callback Pierrick Bouvier @ 2026-10-08 9:42 ` Daniel P. Berrangé 2026-10-08 9:46 ` Yonggang Luo 0 siblings, 1 reply; 62+ messages in thread From: Daniel P. Berrangé @ 2026-10-08 9:42 UTC (permalink / raw) To: Pierrick Bouvier Cc: Yonggang Luo, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny 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/ar_coT44h5-zJPVV@redhat.com/ > > 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. With regards, Daniel -- |: https://berrange.com ~~ https://hachyderm.io/@berrange :| |: https://libvirt.org ~~ https://entangle-photo.org :| |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :| ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-08 9:42 ` Daniel P. Berrangé @ 2026-10-08 9:46 ` Yonggang Luo 2026-10-08 16:06 ` Pierrick Bouvier 0 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-08 9:46 UTC (permalink / raw) To: Daniel P. Berrangé Cc: Pierrick Bouvier, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ > > > > 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? > > With regards, > Daniel > -- > |: https://berrange.com ~~ https://hachyderm.io/@berrange :| > |: https://libvirt.org ~~ https://entangle-photo.org :| > |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :| > -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-08 9:46 ` Yonggang Luo @ 2026-10-08 16:06 ` Pierrick Bouvier 2026-10-08 17:13 ` Yonggang Luo 0 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-08 16:06 UTC (permalink / raw) To: luoyonggang, Daniel P. Berrangé Cc: qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/8/2026 2:46 AM, Yonggang Luo wrote: > On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ >>> >>> 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. >> >> With regards, >> Daniel >> -- >> |: https://berrange.com ~~ https://hachyderm.io/@berrange :| >> |: https://libvirt.org ~~ https://entangle-photo.org :| >> |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :| >> > > ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-08 16:06 ` Pierrick Bouvier @ 2026-10-08 17:13 ` Yonggang Luo 2026-10-08 18:34 ` Pierrick Bouvier 0 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-08 17:13 UTC (permalink / raw) To: Pierrick Bouvier Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/8/2026 2:46 AM, Yonggang Luo wrote: > > On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ > >>> > >>> 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. 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. 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 > > >> > >> With regards, > >> Daniel > >> -- > >> |: https://berrange.com ~~ https://hachyderm.io/@berrange :| > >> |: https://libvirt.org ~~ https://entangle-photo.org :| > >> |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :| > >> > > > > > -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-08 17:13 ` Yonggang Luo @ 2026-10-08 18:34 ` Pierrick Bouvier 2026-10-08 18:48 ` Yonggang Luo ` (2 more replies) 0 siblings, 3 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-08 18:34 UTC (permalink / raw) To: luoyonggang Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/8/2026 10:13 AM, Yonggang Luo wrote: > On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> wrote: >> >> On 10/8/2026 2:46 AM, Yonggang Luo wrote: >>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ >>>>> >>>>> 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. Regards, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-08 18:34 ` Pierrick Bouvier @ 2026-10-08 18:48 ` Yonggang Luo 2026-10-11 20:22 ` Yonggang Luo 2026-10-11 20:32 ` Yonggang Luo 2 siblings, 0 replies; 62+ messages in thread From: Yonggang Luo @ 2026-10-08 18:48 UTC (permalink / raw) To: Pierrick Bouvier Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Fri, Oct 9, 2026 at 2:34 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/8/2026 10:13 AM, Yonggang Luo wrote: > > On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> wrote: > >> > >> On 10/8/2026 2:46 AM, Yonggang Luo wrote: > >>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ > >>>>> > >>>>> 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. That makes sense, I am afraid I have no time to trace it currently(at least a month). At least we now have a good agreement. So it should be much easier, otherwise it's really frustrating. > 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. > > Regards, > Pierrick -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-08 18:34 ` Pierrick Bouvier 2026-10-08 18:48 ` Yonggang Luo @ 2026-10-11 20:22 ` Yonggang Luo 2026-10-12 2:13 ` Pierrick Bouvier 2026-10-11 20:32 ` Yonggang Luo 2 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-11 20:22 UTC (permalink / raw) To: Pierrick Bouvier Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Fri, Oct 9, 2026 at 2:34 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/8/2026 10:13 AM, Yonggang Luo wrote: > > On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> wrote: > >> > >> On 10/8/2026 2:46 AM, Yonggang Luo wrote: > >>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ > >>>>> > >>>>> 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? > > Regards, > Pierrick -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-11 20:22 ` Yonggang Luo @ 2026-10-12 2:13 ` Pierrick Bouvier 2026-10-12 2:21 ` Yonggang Luo 2026-10-12 2:25 ` Pierrick Bouvier 0 siblings, 2 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-12 2:13 UTC (permalink / raw) To: luoyonggang Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/11/26 1:22 PM, Yonggang Luo wrote: > On Fri, Oct 9, 2026 at 2:34 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> wrote: >> >> On 10/8/2026 10:13 AM, Yonggang Luo wrote: >>> On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier >>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>> >>>> On 10/8/2026 2:46 AM, Yonggang Luo wrote: >>>>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ >>>>>>> >>>>>>> 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 >> >> Regards, >> Pierrick > > > ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-12 2:13 ` Pierrick Bouvier @ 2026-10-12 2:21 ` Yonggang Luo 2026-10-12 2:25 ` Pierrick Bouvier 1 sibling, 0 replies; 62+ messages in thread From: Yonggang Luo @ 2026-10-12 2:21 UTC (permalink / raw) To: Pierrick Bouvier Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Mon, Oct 12, 2026 at 10:13 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/11/26 1:22 PM, Yonggang Luo wrote: > > On Fri, Oct 9, 2026 at 2:34 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> wrote: > >> > >> On 10/8/2026 10:13 AM, Yonggang Luo wrote: > >>> On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier > >>> <pierrick.bouvier@oss.qualcomm.com> wrote: > >>>> > >>>> On 10/8/2026 2:46 AM, Yonggang Luo wrote: > >>>>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ > >>>>>>> > >>>>>>> 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 Hi Pierrick These two I can handle it properly, only for the "virt" machine I can not handle it properly What you suggest, it's a must-be requirement now. for example, cpu_max_v8_register_type can be handle in such way: 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) register_accel_target_type: accel/accel-common.c | 21 ++++++--------------- include/accel/accel-cpu-target.h | 3 +-- include/accel/accel-cpu.h | 2 ++ 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/accel/accel-common.c b/accel/accel-common.c index 00a400243f0..c4c365f38c7 100644 --- a/accel/accel-common.c +++ b/accel/accel-common.c @@ -126,21 +126,12 @@ static const TypeInfo accel_types[] = { .instance_size = sizeof(AccelState), .abstract = true, }, + { + .name = TYPE_ACCEL_CPU, + .parent = TYPE_OBJECT, + .abstract = true, + .class_size = sizeof(AccelCPUClass), + }, }; DEFINE_TYPES(accel_types) - -static void register_accel_target_type(void) -{ - g_autofree char *name = g_strconcat("accel-", target_cpu_type(), NULL); - const TypeInfo accel_cpu_type = { - .name = name, - .parent = TYPE_OBJECT, - .abstract = true, - .class_size = sizeof(AccelCPUClass), - }; - - type_register_static(&accel_cpu_type); -} - -type_init(register_accel_target_type); diff --git a/include/accel/accel-cpu-target.h b/include/accel/accel-cpu-target.h index 6feb344e29b..cf33ebd79fc 100644 --- a/include/accel/accel-cpu-target.h +++ b/include/accel/accel-cpu-target.h @@ -24,8 +24,7 @@ #include "accel/accel-cpu.h" #include "cpu.h" -#define TYPE_ACCEL_CPU "accel-" CPU_RESOLVING_TYPE -#define ACCEL_CPU_NAME(name) (name "-" TYPE_ACCEL_CPU) +#define ACCEL_CPU_NAME(name) (name "-accel-" CPU_RESOLVING_TYPE) DECLARE_CLASS_CHECKERS(AccelCPUClass, ACCEL_CPU, TYPE_ACCEL_CPU) #endif /* ACCEL_CPU_H */ diff --git a/include/accel/accel-cpu.h b/include/accel/accel-cpu.h index 9e7eede7c3c..5cfc2b24223 100644 --- a/include/accel/accel-cpu.h +++ b/include/accel/accel-cpu.h @@ -12,6 +12,8 @@ #include "qom/object.h" #include "hw/core/cpu.h" +#define TYPE_ACCEL_CPU "accel-cpu" + typedef struct AccelCPUClass { ObjectClass parent_class; > > > >> > >> Regards, > >> Pierrick > > > > > > > -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-12 2:13 ` Pierrick Bouvier 2026-10-12 2:21 ` Yonggang Luo @ 2026-10-12 2:25 ` Pierrick Bouvier 2026-10-12 4:26 ` Yonggang Luo 1 sibling, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-12 2:25 UTC (permalink / raw) To: luoyonggang Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny 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 >> <pierrick.bouvier@oss.qualcomm.com> wrote: >>> >>> On 10/8/2026 10:13 AM, Yonggang Luo wrote: >>>> On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier >>>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>>> >>>>> On 10/8/2026 2:46 AM, Yonggang Luo wrote: >>>>>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ >>>>>>>> >>>>>>>> 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. 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. It's a work we'll need to do for heterogeneous anyway, I was just hoping to delay that until there, but seems we need to deal with it now. A good thing is that it means target-info won't have to be registered before all QOM types anymore, so it's worth the effort IMHO. Thanks, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-12 2:25 ` Pierrick Bouvier @ 2026-10-12 4:26 ` Yonggang Luo 2026-10-12 7:11 ` Pierrick Bouvier 2026-10-13 1:26 ` Pierrick Bouvier 0 siblings, 2 replies; 62+ messages in thread From: Yonggang Luo @ 2026-10-12 4:26 UTC (permalink / raw) To: Pierrick Bouvier Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Mon, Oct 12, 2026 at 10:25 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> 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 > >> <pierrick.bouvier@oss.qualcomm.com> wrote: > >>> > >>> On 10/8/2026 10:13 AM, Yonggang Luo wrote: > >>>> On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier > >>>> <pierrick.bouvier@oss.qualcomm.com> wrote: > >>>>> > >>>>> On 10/8/2026 2:46 AM, Yonggang Luo wrote: > >>>>>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ > >>>>>>>> > >>>>>>>> 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)? > > 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. > > It's a work we'll need to do for heterogeneous anyway, I was just hoping > to delay that until there, but seems we need to deal with it now. > A good thing is that it means target-info won't have to be registered > before all QOM types anymore, so it's worth the effort IMHO. > > Thanks, > Pierrick -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-12 4:26 ` Yonggang Luo @ 2026-10-12 7:11 ` Pierrick Bouvier 2026-10-13 1:26 ` Pierrick Bouvier 1 sibling, 0 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-12 7:11 UTC (permalink / raw) To: luoyonggang Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/11/26 9:26 PM, Yonggang Luo wrote: > On Mon, Oct 12, 2026 at 10:25 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> 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 >>>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>>> >>>>> On 10/8/2026 10:13 AM, Yonggang Luo wrote: >>>>>> On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier >>>>>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>>>>> >>>>>>> On 10/8/2026 2:46 AM, Yonggang Luo wrote: >>>>>>>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ >>>>>>>>>> >>>>>>>>>> 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)? > We can use is_available as an intermediate step. The good thing is that removing target_* from class_init can be done as much incrementally as we want: there is no need to do all the changes at once. Once we get to the point where there is no target_* in class_init and all types are properly defined with is_available filters, we can see how to deal with the duplication. My point of view after our discussions is that we should keep current name for existing binaries, and should be free to force user to deal with ambiguity with new single-binary (machine type "X" is ambiguous, please choose among arch-X, arch-Y, ...). > >> >> 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. > The alias series you posted initially was good, with the addition to detect when multiple machines have the same alias (and report an error in this case). I triggered the conversation we are having now because things have not been defined properly, and the direction to have -target + arch:machine was not really satisfactory. Now we settled on excluding -target, and embedding all types, I think it's clearer. > >> >> It's a work we'll need to do for heterogeneous anyway, I was just hoping >> to delay that until there, but seems we need to deal with it now. >> A good thing is that it means target-info won't have to be registered >> before all QOM types anymore, so it's worth the effort IMHO. >> >> Thanks, >> Pierrick > > > ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-12 4:26 ` Yonggang Luo 2026-10-12 7:11 ` Pierrick Bouvier @ 2026-10-13 1:26 ` Pierrick Bouvier 2026-10-13 2:43 ` Yonggang Luo 1 sibling, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-13 1:26 UTC (permalink / raw) To: luoyonggang Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/11/26 9:26 PM, Yonggang Luo wrote: > On Mon, Oct 12, 2026 at 10:25 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> 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 >>>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>>> >>>>> On 10/8/2026 10:13 AM, Yonggang Luo wrote: >>>>>> On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier >>>>>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>>>>> >>>>>>> On 10/8/2026 2:46 AM, Yonggang Luo wrote: >>>>>>>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ >>>>>>>>>> >>>>>>>>>> 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 ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-13 1:26 ` Pierrick Bouvier @ 2026-10-13 2:43 ` Yonggang Luo 2026-10-13 3:53 ` Pierrick Bouvier 0 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-13 2:43 UTC (permalink / raw) To: Pierrick Bouvier Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Tue, Oct 13, 2026 at 9:26 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/11/26 9:26 PM, Yonggang Luo wrote: > > On Mon, Oct 12, 2026 at 10:25 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> 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 > >>>> <pierrick.bouvier@oss.qualcomm.com> wrote: > >>>>> > >>>>> On 10/8/2026 10:13 AM, Yonggang Luo wrote: > >>>>>> On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier > >>>>>> <pierrick.bouvier@oss.qualcomm.com> wrote: > >>>>>>> > >>>>>>> On 10/8/2026 2:46 AM, Yonggang Luo wrote: > >>>>>>>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ > >>>>>>>>>> > >>>>>>>>>> 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? 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. because "is_available" depends on target_info(),(we won't have target_info() till the machine is selected). > > Regards, > Pierrick -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-13 2:43 ` Yonggang Luo @ 2026-10-13 3:53 ` Pierrick Bouvier 2026-10-13 4:03 ` Yonggang Luo 0 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-13 3:53 UTC (permalink / raw) To: luoyonggang Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/12/26 7:43 PM, Yonggang Luo wrote: > On Tue, Oct 13, 2026 at 9:26 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> wrote: >> >> On 10/11/26 9:26 PM, Yonggang Luo wrote: >>> On Mon, Oct 12, 2026 at 10:25 AM Pierrick Bouvier >>> <pierrick.bouvier@oss.qualcomm.com> 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 >>>>>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>>>>> >>>>>>> On 10/8/2026 10:13 AM, Yonggang Luo wrote: >>>>>>>> On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier >>>>>>>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>>>>>>> >>>>>>>>> On 10/8/2026 2:46 AM, Yonggang Luo wrote: >>>>>>>>>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ >>>>>>>>>>>> >>>>>>>>>>>> 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. > > 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. Regards, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-13 3:53 ` Pierrick Bouvier @ 2026-10-13 4:03 ` Yonggang Luo 2026-10-13 15:56 ` Pierrick Bouvier 0 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-13 4:03 UTC (permalink / raw) To: Pierrick Bouvier Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Tue, Oct 13, 2026 at 11:53 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/12/26 7:43 PM, Yonggang Luo wrote: > > On Tue, Oct 13, 2026 at 9:26 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> wrote: > >> > >> On 10/11/26 9:26 PM, Yonggang Luo wrote: > >>> On Mon, Oct 12, 2026 at 10:25 AM Pierrick Bouvier > >>> <pierrick.bouvier@oss.qualcomm.com> 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 > >>>>>> <pierrick.bouvier@oss.qualcomm.com> wrote: > >>>>>>> > >>>>>>> On 10/8/2026 10:13 AM, Yonggang Luo wrote: > >>>>>>>> On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier > >>>>>>>> <pierrick.bouvier@oss.qualcomm.com> wrote: > >>>>>>>>> > >>>>>>>>> On 10/8/2026 2:46 AM, Yonggang Luo wrote: > >>>>>>>>>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ > >>>>>>>>>>>> > >>>>>>>>>>>> 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 ^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-13 4:03 ` Yonggang Luo @ 2026-10-13 15:56 ` Pierrick Bouvier 0 siblings, 0 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-13 15:56 UTC (permalink / raw) To: luoyonggang Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/12/2026 9:03 PM, Yonggang Luo wrote: > On Tue, Oct 13, 2026 at 11:53 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> wrote: >> >> On 10/12/26 7:43 PM, Yonggang Luo wrote: >>> On Tue, Oct 13, 2026 at 9:26 AM Pierrick Bouvier >>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>> >>>> On 10/11/26 9:26 PM, Yonggang Luo wrote: >>>>> On Mon, Oct 12, 2026 at 10:25 AM Pierrick Bouvier >>>>> <pierrick.bouvier@oss.qualcomm.com> 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 >>>>>>>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>>>>>>> >>>>>>>>> On 10/8/2026 10:13 AM, Yonggang Luo wrote: >>>>>>>>>> On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier >>>>>>>>>> <pierrick.bouvier@oss.qualcomm.com> wrote: >>>>>>>>>>> >>>>>>>>>>> On 10/8/2026 2:46 AM, Yonggang Luo wrote: >>>>>>>>>>>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ >>>>>>>>>>>>>> >>>>>>>>>>>>>> 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 ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-08 18:34 ` Pierrick Bouvier 2026-10-08 18:48 ` Yonggang Luo 2026-10-11 20:22 ` Yonggang Luo @ 2026-10-11 20:32 ` Yonggang Luo 2 siblings, 0 replies; 62+ messages in thread From: Yonggang Luo @ 2026-10-11 20:32 UTC (permalink / raw) To: Pierrick Bouvier Cc: Daniel P. Berrangé, qemu-devel, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Fri, Oct 9, 2026 at 2:34 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/8/2026 10:13 AM, Yonggang Luo wrote: > > On Fri, Oct 9, 2026 at 12:06 AM Pierrick Bouvier > > <pierrick.bouvier@oss.qualcomm.com> wrote: > >> > >> On 10/8/2026 2:46 AM, Yonggang Luo wrote: > >>> On Thu, Oct 8, 2026 at 5:42 PM Daniel P. Berrangé <berrange@redhat.com> 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/ar_coT44h5-zJPVV@redhat.com/ > >>>>> > >>>>> 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. > > Regards, > Pierrick Hi Pierrick, this is something I have to do, please have a look target-info.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/target-info.c b/target-info.c index 6c5c732eba9..b5d0dce1a87 100644 --- a/target-info.c +++ b/target-info.c @@ -43,55 +43,61 @@ bool target_big_endian(void) return target_endian_mode() == ENDIAN_MODE_BIG; } +static bool target_arch_matches(uint64_t mask) +{ + return target_combined_binary() || + (mask & (1ULL << target_arch())) != 0; +} + bool target_base_arm(void) { - return (QEMU_ARCH_ARM & (1ULL << target_arch())) != 0; + return target_arch_matches(QEMU_ARCH_ARM); } bool target_arm(void) { - return target_arch() == EMU_TARGET_ARM || - target_arch() == EMU_TARGET_ARMEB; + return target_arch_matches((1ULL << EMU_TARGET_ARM) | + (1ULL << EMU_TARGET_ARMEB)); } bool target_aarch64(void) { - return target_arch() == EMU_TARGET_AARCH64 || - target_arch() == EMU_TARGET_AARCH64_BE; + return target_arch_matches((1ULL << EMU_TARGET_AARCH64) | + (1ULL << EMU_TARGET_AARCH64_BE)); } bool target_m68k(void) { - return target_arch() == EMU_TARGET_M68K; + return target_arch_matches(1ULL << EMU_TARGET_M68K); } bool target_or1k(void) { - return target_arch() == EMU_TARGET_OR1K; + return target_arch_matches(1ULL << EMU_TARGET_OR1K); } bool target_base_ppc(void) { - return (QEMU_ARCH_PPC & (1ULL << target_arch())) != 0; + return target_arch_matches(QEMU_ARCH_PPC); } bool target_ppc(void) { - return target_arch() == EMU_TARGET_PPC; + return target_arch_matches(1ULL << EMU_TARGET_PPC); } bool target_ppc64(void) { - return target_arch() == EMU_TARGET_PPC64 || - target_arch() == EMU_TARGET_PPC64LE; + return target_arch_matches((1ULL << EMU_TARGET_PPC64) | + (1ULL << EMU_TARGET_PPC64LE)); } bool target_s390x(void) { - return target_arch() == EMU_TARGET_S390X; + return target_arch_matches(1ULL << EMU_TARGET_S390X); } bool target_riscv64(void) { - return target_arch() == EMU_TARGET_RISCV64; + return target_arch_matches(1ULL << EMU_TARGET_RISCV64); } -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-07 11:47 [PATCH 0/8] qom: pass TargetInfo to the is_available callback Yonggang Luo ` (8 preceding siblings ...) 2026-10-07 20:25 ` [PATCH 0/8] qom: pass TargetInfo to the is_available callback Pierrick Bouvier @ 2026-10-07 20:46 ` Pierrick Bouvier 2026-10-09 21:58 ` Pierrick Bouvier 9 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-07 20:46 UTC (permalink / raw) To: Yonggang Luo, qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny 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 > ``` > > It moves target_info() to a shared location so object.c can call it when > checking machine availability. The series also replaces QOM-based target-info > registration with a constructor list and passes TargetInfo to the > is_available callback. > > Target metadata and architecture checks are generated from the configured > targets, there is too much arch to write biiolperate code. doing this for easier > Add TargetInfo* to is_available > > The target-info API and implementation are shared, rather than compiled > separately for every target. > > This series removes the per-target source files "configs/targets/*.c". > Their target-specific parameters are collected in a generated > target-info-def.c for each softmmu target. This lays the groundwork for > QEMU system builds in which target-info-def.c is the only target-specific > source file compiled for each target. Using the same filename lets > meson.build handle these definitions uniformly. > > The series adds unit-test coverage for target info and multi-target builds. > > Pierrick Bouvier (2): > configs/targets: remove target info definitions > target-info: rename target-info-stub.c in target-info-def.c > > Yonggang Luo (6): > target-info: rename target-info-impl.h to target-info-def.h > target-info: replace QOM registration with a constructor list > tests/unit: add target-info coverage for multi-target builds > meson: load all target .mak files into target_mak_all > target-info: Replace handwritten architecture checks with generated > code > qom: pass TargetInfo to is_available for later use > > MAINTAINERS | 2 +- > configs/targets/aarch64-softmmu.c | 25 ------ > configs/targets/arm-softmmu.c | 25 ------ > configs/targets/meson.build | 6 -- > configs/targets/riscv32-softmmu.c | 24 ----- > configs/targets/riscv64-softmmu.c | 24 ----- > hw/arm/aspeed_ast27x0-fc.c | 2 +- > hw/arm/aspeed_ast27x0_evb.c | 4 +- > hw/arm/raspi.c | 4 +- > hw/arm/raspi4b.c | 2 +- > hw/arm/virt.c | 4 +- > hw/m68k/virt.c | 4 +- > hw/or1k/virt.c | 2 +- > include/hw/core/cpu.h | 2 +- > include/qemu/module.h | 1 - > include/qemu/target-info-def.h | 88 ++++++++++++++++++ > include/qemu/target-info-impl.h | 42 --------- > include/qemu/target-info-init.h | 53 ----------- > include/qemu/target-info-qom.h | 31 ------- > include/qemu/target-info.h | 87 ++++-------------- > include/qom/object.h | 12 ++- > meson.build | 52 ++++++++--- > page-vary-common.c | 2 +- > page-vary-system.c | 2 +- > qom/object.c | 3 +- > scripts/gen-target-info.py | 99 ++++++++++++++++++++ > system/vl.c | 4 - > target-info-stub.c => target-info-def.c | 3 +- > target-info-qom.c | 60 ------------- > target-info.c | 115 ++++++++++++------------ > tests/qtest/fuzz/fuzz.c | 3 - > tests/unit/meson.build | 4 + > tests/unit/test-multi-target.c | 12 +-- > tests/unit/test-target-info.c | 38 ++++++++ > 34 files changed, 379 insertions(+), 462 deletions(-) > delete mode 100644 configs/targets/aarch64-softmmu.c > delete mode 100644 configs/targets/arm-softmmu.c > delete mode 100644 configs/targets/meson.build > delete mode 100644 configs/targets/riscv32-softmmu.c > delete mode 100644 configs/targets/riscv64-softmmu.c > create mode 100644 include/qemu/target-info-def.h > delete mode 100644 include/qemu/target-info-impl.h > delete mode 100644 include/qemu/target-info-init.h > delete mode 100644 include/qemu/target-info-qom.h > create mode 100644 scripts/gen-target-info.py > rename target-info-stub.c => target-info-def.c (94%) > delete mode 100644 target-info-qom.c > create mode 100644 tests/unit/test-target-info.c > I'll pull the first three patches. Regards, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-07 20:46 ` Pierrick Bouvier @ 2026-10-09 21:58 ` Pierrick Bouvier 2026-10-09 22:08 ` Yonggang Luo 0 siblings, 1 reply; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-09 21:58 UTC (permalink / raw) To: Yonggang Luo, qemu-devel Cc: Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/7/2026 1:46 PM, Pierrick Bouvier wrote: > > I'll pull the first three patches. > Now merged upstream (40ba85501c0b6ac2a7319d3804dab072edf67564) Thanks, Pierrick ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-09 21:58 ` Pierrick Bouvier @ 2026-10-09 22:08 ` Yonggang Luo 2026-10-09 22:21 ` Pierrick Bouvier 0 siblings, 1 reply; 62+ messages in thread From: Yonggang Luo @ 2026-10-09 22:08 UTC (permalink / raw) To: Pierrick Bouvier Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On Sat, Oct 10, 2026 at 5:58 AM Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> wrote: > > On 10/7/2026 1:46 PM, Pierrick Bouvier wrote: > > > > I'll pull the first three patches. > > > > Now merged upstream (40ba85501c0b6ac2a7319d3804dab072edf67564) > Hi Pierrick Seems you post to the wrong place. > Thanks, > Pierrick -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo ^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 0/8] qom: pass TargetInfo to the is_available callback 2026-10-09 22:08 ` Yonggang Luo @ 2026-10-09 22:21 ` Pierrick Bouvier 0 siblings, 0 replies; 62+ messages in thread From: Pierrick Bouvier @ 2026-10-09 22:21 UTC (permalink / raw) To: luoyonggang Cc: qemu-devel, Daniel P. Berrangé, Cleber Rosa, Stefan Hajnoczi, Cédric Le Goater, Laurent Vivier, Zhao Liu, John Snow, Laurent Vivier, Richard Henderson, Joel Stanley, Fabiano Rosas, Kane Chen, Andrew Jeffery, Troy Lee, Jamin Lin, Stafford Horne, qemu-arm, Philippe Mathieu-Daude, Peter Maydell, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau, Steven Lee, Alexander Bulekov, Darren Kenny On 10/9/2026 3:08 PM, Yonggang Luo wrote: > On Sat, Oct 10, 2026 at 5:58 AM Pierrick Bouvier > <pierrick.bouvier@oss.qualcomm.com> wrote: >> >> On 10/7/2026 1:46 PM, Pierrick Bouvier wrote: >>> >>> I'll pull the first three patches. >>> >> >> Now merged upstream (40ba85501c0b6ac2a7319d3804dab072edf67564) >> > > Hi Pierrick > Seems you post to the wrong place. > Hi Yonggang, oops sorry indeed. I was waiting for previous patches to be merged to send those ones. ^ permalink raw reply [flat|nested] 62+ messages in thread
end of thread, other threads:[~2026-10-13 15:56 UTC | newest] Thread overview: 62+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-07 11:47 [PATCH 0/8] qom: pass TargetInfo to the is_available callback Yonggang Luo 2026-10-07 11:47 ` [PATCH 1/8] configs/targets: remove target info definitions Yonggang Luo 2026-10-07 20:26 ` Pierrick Bouvier 2026-10-08 9:46 ` Philippe Mathieu-Daudé 2026-10-07 11:47 ` [PATCH 2/8] target-info: rename target-info-stub.c in target-info-def.c Yonggang Luo 2026-10-07 11:48 ` [PATCH 3/8] target-info: rename target-info-impl.h to target-info-def.h Yonggang Luo 2026-10-07 20:27 ` Pierrick Bouvier 2026-10-07 11:48 ` [PATCH 4/8] target-info: replace QOM registration with a constructor list Yonggang Luo 2026-10-07 20:29 ` Pierrick Bouvier 2026-10-07 20:50 ` Yonggang Luo 2026-10-07 22:31 ` Pierrick Bouvier 2026-10-07 22:54 ` Yonggang Luo 2026-10-07 23:24 ` Pierrick Bouvier 2026-10-13 9:26 ` Daniel P. Berrangé 2026-10-13 15:53 ` Pierrick Bouvier 2026-10-07 23:02 ` Yonggang Luo 2026-10-07 23:28 ` Pierrick Bouvier 2026-10-12 21:27 ` Yonggang Luo 2026-10-13 3:57 ` Pierrick Bouvier 2026-10-13 8:58 ` Yonggang Luo 2026-10-07 11:48 ` [PATCH 5/8] tests/unit: add target-info coverage for multi-target builds Yonggang Luo 2026-10-07 11:48 ` [PATCH 6/8] meson: load all target .mak files into target_mak_all Yonggang Luo 2026-10-07 20:30 ` Pierrick Bouvier 2026-10-07 11:48 ` [PATCH 7/8] target-info: Replace handwritten architecture checks with generated code Yonggang Luo 2026-10-07 20:36 ` Pierrick Bouvier 2026-10-07 11:48 ` [PATCH 8/8] qom: pass TargetInfo to is_available for later use Yonggang Luo 2026-10-07 20:44 ` Pierrick Bouvier 2026-10-07 21:42 ` Yonggang Luo 2026-10-08 0:00 ` Pierrick Bouvier 2026-10-08 0:03 ` Pierrick Bouvier 2026-10-08 2:08 ` Yonggang Luo 2026-10-08 15:58 ` Pierrick Bouvier 2026-10-08 9:36 ` Daniel P. Berrangé 2026-10-08 9:56 ` Yonggang Luo 2026-10-08 16:01 ` Pierrick Bouvier 2026-10-08 17:04 ` Yonggang Luo 2026-10-08 18:26 ` Pierrick Bouvier 2026-10-08 18:33 ` Yonggang Luo 2026-10-08 18:40 ` Pierrick Bouvier 2026-10-07 20:25 ` [PATCH 0/8] qom: pass TargetInfo to the is_available callback Pierrick Bouvier 2026-10-08 9:42 ` Daniel P. Berrangé 2026-10-08 9:46 ` Yonggang Luo 2026-10-08 16:06 ` Pierrick Bouvier 2026-10-08 17:13 ` Yonggang Luo 2026-10-08 18:34 ` Pierrick Bouvier 2026-10-08 18:48 ` Yonggang Luo 2026-10-11 20:22 ` Yonggang Luo 2026-10-12 2:13 ` Pierrick Bouvier 2026-10-12 2:21 ` Yonggang Luo 2026-10-12 2:25 ` Pierrick Bouvier 2026-10-12 4:26 ` Yonggang Luo 2026-10-12 7:11 ` Pierrick Bouvier 2026-10-13 1:26 ` Pierrick Bouvier 2026-10-13 2:43 ` Yonggang Luo 2026-10-13 3:53 ` Pierrick Bouvier 2026-10-13 4:03 ` Yonggang Luo 2026-10-13 15:56 ` Pierrick Bouvier 2026-10-11 20:32 ` Yonggang Luo 2026-10-07 20:46 ` Pierrick Bouvier 2026-10-09 21:58 ` Pierrick Bouvier 2026-10-09 22:08 ` Yonggang Luo 2026-10-09 22:21 ` Pierrick Bouvier
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.