[PATCH v2 00/13] single-binary: link ARM and RISC-V into qemu-system

Yonggang Luo posted 13 patches 2 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260826184229.1145-1-luoyonggang@gmail.com
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, "Philippe Mathieu-Daudé" <philmd@mailo.com>, Peter Maydell <peter.maydell@linaro.org>, "Michael S. Tsirkin" <mst@redhat.com>, Igor Mammedov <imammedo@redhat.com>, Ani Sinha <anisinha@redhat.com>, Zhao Liu <zhao1.liu@intel.com>, Song Gao <17746591750@163.com>, Bibo Mao <maobibo@loongson.cn>, Xianglai Li <lixianglai@loongson.cn>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Sunil V L <sunilvl@ventanamicro.com>, Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Chao Liu <chao.liu@processmission.com>, Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>, "Alex Bennée" <alex.bennee@linaro.org>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, Aurelien Jarno <aurelien@aurel32.net>, Aleksandar Rikalo <arikalo@gmail.com>, Nicholas Piggin <npiggin@gmail.com>, Chinmay Rath <rathc@linux.ibm.com>, Glenn Miles <milesg@linux.ibm.com>, Harsh Prateek Bora <harshpb@linux.ibm.com>, Cornelia Huck <cohuck@redhat.com>, Eric Farman <farman@linux.ibm.com>, Matthew Rosato <mjrosato@linux.ibm.com>, Ilya Leoshkevich <iii@linux.ibm.com>, David Hildenbrand <david@kernel.org>, Alexander Bulekov <alxndr@bu.edu>, Stefan Hajnoczi <stefanha@redhat.com>, Fabiano Rosas <farosas@suse.de>, Darren Kenny <darren.kenny@oracle.com>, Laurent Vivier <lvivier@redhat.com>
MAINTAINERS                                   |  1 -
accel/accel-common.c                          | 21 ++---
hw/arm/virt-acpi-build.c                      |  4 +-
hw/arm/virt.c                                 | 17 ++--
hw/core/cpu-system.c                          | 23 ++++++
hw/core/machine-qmp-cmds.c                    | 26 +++++++
hw/core/machine.c                             |  6 ++
hw/loongarch/virt-acpi-build.c                |  6 +-
hw/loongarch/virt.c                           |  2 +-
hw/riscv/virt-acpi-build.c                    |  2 +-
hw/riscv/virt.c                               | 12 ++-
include/accel/accel-cpu-target.h              |  3 +-
include/accel/accel-cpu.h                     |  2 +
include/hw/arm/virt.h                         |  6 +-
include/hw/core/boards.h                      | 12 ++-
include/hw/loongarch/virt.h                   |  2 +-
include/hw/riscv/virt.h                       |  6 +-
include/qemu/target-info-qom.h                | 42 +++++++++-
include/semihosting/common-semi.h             | 56 ++++++++++++--
meson.build                                   | 69 ++++++++++++++++-
meson_options.txt                             |  2 +
qemu-options.hx                               |  8 ++
scripts/meson-buildoptions.sh                 |  3 +
stubs/dump.c                                  | 27 -------
stubs/meson.build                             |  2 -
stubs/qmp-cpu.c                               | 21 -----
system/vl.c                                   | 44 ++++++++---
target-info-qom.c                             | 77 +++++++++++++++++--
target-info.c                                 | 32 ++++++++
target/arm/arch_dump.c                        |  8 +-
target/arm/arm-qmp-cmds.c                     | 15 +++-
target/arm/common-semi-target.c               | 23 ++++--
target/arm/meson.build                        |  7 +-
target/i386/arch_dump.c                       |  8 +-
target/i386/cpu-system.c                      | 12 ++-
target/i386/cpu.c                             |  6 +-
target/loongarch/arch_dump.c                  |  8 +-
target/loongarch/loongarch-qmp-cmds.c         | 15 +++-
target/mips/system/mips-qmp-cmds.c            | 15 ++--
target/ppc/arch_dump.c                        |  8 +-
target/ppc/ppc-qmp-cmds.c                     | 15 ++--
target/riscv/arch_dump.c                      |  8 +-
target/riscv/common-semi-target.c             | 25 ++++--
target/riscv/helper.h                         |  6 +-
target/riscv/meson.build                      |  4 +-
target/riscv/riscv-qmp-cmds.c                 | 15 +++-
target/riscv/tcg/bitmanip_helper.c            |  4 +-
.../tcg/insn_trans/trans_privileged.c.inc     |  2 +-
target/riscv/tcg/insn_trans/trans_xlrbr.c.inc |  4 +-
target/riscv/tcg/op_helper.c                  |  2 +-
target/s390x/arch_dump.c                      |  8 +-
target/s390x/cpu_models_system.c              | 15 +++-
tests/qtest/fuzz/fuzz.c                       |  2 +-
53 files changed, 562 insertions(+), 207 deletions(-)
delete mode 100644 stubs/dump.c
delete mode 100644 stubs/qmp-cpu.c
[PATCH v2 00/13] single-binary: link ARM and RISC-V into qemu-system
Posted by Yonggang Luo 2 weeks ago
This series produces one qemu-system binary that can run ARM (32 and 64)
and RISC-V (32 and 64). It follows Pierrick Bouvier's merged series
"single-binary: implement dynamic filtering for machine types":

  https://patchew.org/QEMU/20260724000948.234657-1-pierrick.bouvier@oss.qualcomm.com/

That work added TYPE_TARGET_SPECIFIC so machines can be filtered per
target in one process. This series uniquifies remaining per-target C
symbols and QOM names, selects TargetInfo at runtime, and links ARM
plus RISC-V into qemu-system.

A combined link cannot keep C symbols or QOM type names that were unique
only because each qemu-system-$arch was a separate binary. The first
patches remove those collisions:

- TYPE_ACCEL_CPU is a single abstract accel-cpu parent, registered once
  next to TYPE_ACCEL. Leaf names still encode the CPU type so
  accel_init_cpu_interfaces() can look up "<accel>-accel-"
  CPU_RESOLVING_TYPE.
- ARM and RISC-V virt QOM names become arm-virt and riscv-virt. The
  boards keep -machine virt via machine_class_set_name() after the
  selected target is applied. Latest ARM virt still sets mc->alias.
- virt ACPI helpers and RISC-V TCG crc32/crc32c/wfi helpers get an arch
  prefix so the combined link does not need meson -D name mangling.
  LoongArch virt_acpi_setup is renamed in the same pass.

Target selection then has to work with more than one TargetInfo in the
process:

- Parse -target before TargetInfo is fixed. The token is target_name
  (arm, aarch64, riscv32, riscv64). When -target is omitted, infer it
  from the program basename (qemu-system-aarch64, strip .exe).
  qemu-system with no arch suffix always requires -target; there is
  no unique-TargetInfo fallback. Use -target ? to list names.
- Combined binaries cannot keep one global C symbol per arch for
  query-cpu-definitions, dump notes, or Angel semihosting. Those
  handlers move onto a process-wide TargetCpuOps table.

The last patch still builds qemu-system-$TARGET. qemu-system is extra,
from the union of ARM and RISC-V Kconfig plus aarch64/riscv64 arch
objects. Do not replace the per-target binaries with symlinks to
qemu-system. Do not add qemu-systemw on Windows: a GUI twin of the
combined binary would keep QEMU exporting data from the .exe into
DLLs, and those data exports cannot be delay-loaded (qdev_prop_array
and other qdev_prop_*). That would block enabling modules globally
on Windows.

Examples:

  qemu-system -target aarch64 -M virt ...
  qemu-system-riscv64 -M virt ...

A combined binary named qemu-system with no arch suffix always
requires -target. A missing or unknown name fails and points at
-target ?.

Changes v1 -> v2:
- Drop little- and big-endian TargetInfo variants from this series.
  v1 registered target-info-<name>-le and -be, selected is_default from
  TARGET_BIG_ENDIAN, and accepted -target tokens such as aarch64-le.
  v2 keeps one TargetInfo per target_name. Endian variants are later
  work, not required to link ARM and RISC-V into qemu-system.
- -target help/? lists target_name only. Unknown names point at
  -target ? rather than printing the list and exit(1).
- qemu-system with no arch suffix always requires -target. v1 could
  still pick a unique TargetInfo when only one was registered.
- Keep qemu-system-$TARGET; qemu-system is an extra binary. v1
  described installing per-arch names as symlinks to qemu-system.
- Do not build qemu-systemw for the combined binary. A Windows GUI
  twin would keep using exe symbols from DLLs, and data exports
  cannot be delay-loaded (qdev_prop_array / qdev_prop_*), which
  would block enabling modules globally on Windows.

Based-on: <20260724000948.234657-1-pierrick.bouvier@oss.qualcomm.com>

Yonggang Luo (13):
  accel: use a shared TYPE_ACCEL_CPU parent
  hw/riscv/virt: register TYPE_TARGET_SPECIFIC
  hw/arm/virt: register TYPE_TARGET_SPECIFIC on the abstract parent
  machine: allow -M name to differ from QOM type
  hw/riscv/virt: use unique QOM name
  hw/arm/virt: use unique QOM name
  hw/arm/virt: prefix ACPI helpers with arm_virt_
  hw/riscv/virt: prefix ACPI helpers with riscv_virt_
  hw/loongarch/virt: prefix ACPI helper with loongarch_virt_
  target/riscv: uniquify TCG crc32, crc32c, and wfi helper names
  system/vl: add new option -target
  target-info: dispatch CPU QMP, dump, and arm/riscv semihosting
  meson: build single binary

 MAINTAINERS                                   |  1 -
 accel/accel-common.c                          | 21 ++---
 hw/arm/virt-acpi-build.c                      |  4 +-
 hw/arm/virt.c                                 | 17 ++--
 hw/core/cpu-system.c                          | 23 ++++++
 hw/core/machine-qmp-cmds.c                    | 26 +++++++
 hw/core/machine.c                             |  6 ++
 hw/loongarch/virt-acpi-build.c                |  6 +-
 hw/loongarch/virt.c                           |  2 +-
 hw/riscv/virt-acpi-build.c                    |  2 +-
 hw/riscv/virt.c                               | 12 ++-
 include/accel/accel-cpu-target.h              |  3 +-
 include/accel/accel-cpu.h                     |  2 +
 include/hw/arm/virt.h                         |  6 +-
 include/hw/core/boards.h                      | 12 ++-
 include/hw/loongarch/virt.h                   |  2 +-
 include/hw/riscv/virt.h                       |  6 +-
 include/qemu/target-info-qom.h                | 42 +++++++++-
 include/semihosting/common-semi.h             | 56 ++++++++++++--
 meson.build                                   | 69 ++++++++++++++++-
 meson_options.txt                             |  2 +
 qemu-options.hx                               |  8 ++
 scripts/meson-buildoptions.sh                 |  3 +
 stubs/dump.c                                  | 27 -------
 stubs/meson.build                             |  2 -
 stubs/qmp-cpu.c                               | 21 -----
 system/vl.c                                   | 44 ++++++++---
 target-info-qom.c                             | 77 +++++++++++++++++--
 target-info.c                                 | 32 ++++++++
 target/arm/arch_dump.c                        |  8 +-
 target/arm/arm-qmp-cmds.c                     | 15 +++-
 target/arm/common-semi-target.c               | 23 ++++--
 target/arm/meson.build                        |  7 +-
 target/i386/arch_dump.c                       |  8 +-
 target/i386/cpu-system.c                      | 12 ++-
 target/i386/cpu.c                             |  6 +-
 target/loongarch/arch_dump.c                  |  8 +-
 target/loongarch/loongarch-qmp-cmds.c         | 15 +++-
 target/mips/system/mips-qmp-cmds.c            | 15 ++--
 target/ppc/arch_dump.c                        |  8 +-
 target/ppc/ppc-qmp-cmds.c                     | 15 ++--
 target/riscv/arch_dump.c                      |  8 +-
 target/riscv/common-semi-target.c             | 25 ++++--
 target/riscv/helper.h                         |  6 +-
 target/riscv/meson.build                      |  4 +-
 target/riscv/riscv-qmp-cmds.c                 | 15 +++-
 target/riscv/tcg/bitmanip_helper.c            |  4 +-
 .../tcg/insn_trans/trans_privileged.c.inc     |  2 +-
 target/riscv/tcg/insn_trans/trans_xlrbr.c.inc |  4 +-
 target/riscv/tcg/op_helper.c                  |  2 +-
 target/s390x/arch_dump.c                      |  8 +-
 target/s390x/cpu_models_system.c              | 15 +++-
 tests/qtest/fuzz/fuzz.c                       |  2 +-
 53 files changed, 562 insertions(+), 207 deletions(-)
 delete mode 100644 stubs/dump.c
 delete mode 100644 stubs/qmp-cpu.c

-- 
2.52.0.windows.1
Re: [PATCH v2 00/13] single-binary: link ARM and RISC-V into qemu-system
Posted by Philippe Mathieu-Daudé 2 weeks ago
On 26/8/26 20:42, Yonggang Luo wrote:

> Changes v1 -> v2:
> - Drop little- and big-endian TargetInfo variants from this series.
>    v1 registered target-info-<name>-le and -be, selected is_default from
>    TARGET_BIG_ENDIAN, and accepted -target tokens such as aarch64-le.
>    v2 keeps one TargetInfo per target_name. Endian variants are later
>    work, not required to link ARM and RISC-V into qemu-system.
> - -target help/? lists target_name only. Unknown names point at
>    -target ? rather than printing the list and exit(1).
> - qemu-system with no arch suffix always requires -target. v1 could
>    still pick a unique TargetInfo when only one was registered.
> - Keep qemu-system-$TARGET; qemu-system is an extra binary. v1
>    described installing per-arch names as symlinks to qemu-system.
> - Do not build qemu-systemw for the combined binary. A Windows GUI
>    twin would keep using exe symbols from DLLs, and data exports
>    cannot be delay-loaded (qdev_prop_array / qdev_prop_*), which
>    would block enabling modules globally on Windows.

FTR I'll wait we finish discussing on your v1 before having a look
at this v2.
Re: [PATCH v2 00/13] single-binary: link ARM and RISC-V into qemu-system
Posted by Pierrick Bouvier 1 week, 5 days ago
On 8/26/2026 11:42 AM, Yonggang Luo wrote:
> This series produces one qemu-system binary that can run ARM (32 and 64)
> and RISC-V (32 and 64). It follows Pierrick Bouvier's merged series
> "single-binary: implement dynamic filtering for machine types":
> 
>   https://patchew.org/QEMU/20260724000948.234657-1-pierrick.bouvier@oss.qualcomm.com/
> 
> That work added TYPE_TARGET_SPECIFIC so machines can be filtered per
> target in one process. This series uniquifies remaining per-target C
> symbols and QOM names, selects TargetInfo at runtime, and links ARM
> plus RISC-V into qemu-system.
> 
> A combined link cannot keep C symbols or QOM type names that were unique
> only because each qemu-system-$arch was a separate binary. The first
> patches remove those collisions:
> 
> - TYPE_ACCEL_CPU is a single abstract accel-cpu parent, registered once
>   next to TYPE_ACCEL. Leaf names still encode the CPU type so
>   accel_init_cpu_interfaces() can look up "<accel>-accel-"
>   CPU_RESOLVING_TYPE.
> - ARM and RISC-V virt QOM names become arm-virt and riscv-virt. The
>   boards keep -machine virt via machine_class_set_name() after the
>   selected target is applied. Latest ARM virt still sets mc->alias.
> - virt ACPI helpers and RISC-V TCG crc32/crc32c/wfi helpers get an arch
>   prefix so the combined link does not need meson -D name mangling.
>   LoongArch virt_acpi_setup is renamed in the same pass.
> 
> Target selection then has to work with more than one TargetInfo in the
> process:
> 
> - Parse -target before TargetInfo is fixed. The token is target_name
>   (arm, aarch64, riscv32, riscv64). When -target is omitted, infer it
>   from the program basename (qemu-system-aarch64, strip .exe).
>   qemu-system with no arch suffix always requires -target; there is
>   no unique-TargetInfo fallback. Use -target ? to list names.
> - Combined binaries cannot keep one global C symbol per arch for
>   query-cpu-definitions, dump notes, or Angel semihosting. Those
>   handlers move onto a process-wide TargetCpuOps table.
> 
> The last patch still builds qemu-system-$TARGET. qemu-system is extra,
> from the union of ARM and RISC-V Kconfig plus aarch64/riscv64 arch
> objects. Do not replace the per-target binaries with symlinks to
> qemu-system. Do not add qemu-systemw on Windows: a GUI twin of the
> combined binary would keep QEMU exporting data from the .exe into
> DLLs, and those data exports cannot be delay-loaded (qdev_prop_array
> and other qdev_prop_*). That would block enabling modules globally
> on Windows.
> 
> Examples:
> 
>   qemu-system -target aarch64 -M virt ...
>   qemu-system-riscv64 -M virt ...
> 
> A combined binary named qemu-system with no arch suffix always
> requires -target. A missing or unknown name fails and points at
> -target ?.
> 
> Changes v1 -> v2:
> - Drop little- and big-endian TargetInfo variants from this series.
>   v1 registered target-info-<name>-le and -be, selected is_default from
>   TARGET_BIG_ENDIAN, and accepted -target tokens such as aarch64-le.
>   v2 keeps one TargetInfo per target_name. Endian variants are later
>   work, not required to link ARM and RISC-V into qemu-system.
> - -target help/? lists target_name only. Unknown names point at
>   -target ? rather than printing the list and exit(1).
> - qemu-system with no arch suffix always requires -target. v1 could
>   still pick a unique TargetInfo when only one was registered.
> - Keep qemu-system-$TARGET; qemu-system is an extra binary. v1
>   described installing per-arch names as symlinks to qemu-system.
> - Do not build qemu-systemw for the combined binary. A Windows GUI
>   twin would keep using exe symbols from DLLs, and data exports
>   cannot be delay-loaded (qdev_prop_array / qdev_prop_*), which
>   would block enabling modules globally on Windows.
> 
> Based-on: <20260724000948.234657-1-pierrick.bouvier@oss.qualcomm.com>
> 
> Yonggang Luo (13):
>   accel: use a shared TYPE_ACCEL_CPU parent
>   hw/riscv/virt: register TYPE_TARGET_SPECIFIC
>   hw/arm/virt: register TYPE_TARGET_SPECIFIC on the abstract parent
>   machine: allow -M name to differ from QOM type
>   hw/riscv/virt: use unique QOM name
>   hw/arm/virt: use unique QOM name
>   hw/arm/virt: prefix ACPI helpers with arm_virt_
>   hw/riscv/virt: prefix ACPI helpers with riscv_virt_
>   hw/loongarch/virt: prefix ACPI helper with loongarch_virt_
>   target/riscv: uniquify TCG crc32, crc32c, and wfi helper names
>   system/vl: add new option -target
>   target-info: dispatch CPU QMP, dump, and arm/riscv semihosting
>   meson: build single binary
> 
>  MAINTAINERS                                   |  1 -
>  accel/accel-common.c                          | 21 ++---
>  hw/arm/virt-acpi-build.c                      |  4 +-
>  hw/arm/virt.c                                 | 17 ++--
>  hw/core/cpu-system.c                          | 23 ++++++
>  hw/core/machine-qmp-cmds.c                    | 26 +++++++
>  hw/core/machine.c                             |  6 ++
>  hw/loongarch/virt-acpi-build.c                |  6 +-
>  hw/loongarch/virt.c                           |  2 +-
>  hw/riscv/virt-acpi-build.c                    |  2 +-
>  hw/riscv/virt.c                               | 12 ++-
>  include/accel/accel-cpu-target.h              |  3 +-
>  include/accel/accel-cpu.h                     |  2 +
>  include/hw/arm/virt.h                         |  6 +-
>  include/hw/core/boards.h                      | 12 ++-
>  include/hw/loongarch/virt.h                   |  2 +-
>  include/hw/riscv/virt.h                       |  6 +-
>  include/qemu/target-info-qom.h                | 42 +++++++++-
>  include/semihosting/common-semi.h             | 56 ++++++++++++--
>  meson.build                                   | 69 ++++++++++++++++-
>  meson_options.txt                             |  2 +
>  qemu-options.hx                               |  8 ++
>  scripts/meson-buildoptions.sh                 |  3 +
>  stubs/dump.c                                  | 27 -------
>  stubs/meson.build                             |  2 -
>  stubs/qmp-cpu.c                               | 21 -----
>  system/vl.c                                   | 44 ++++++++---
>  target-info-qom.c                             | 77 +++++++++++++++++--
>  target-info.c                                 | 32 ++++++++
>  target/arm/arch_dump.c                        |  8 +-
>  target/arm/arm-qmp-cmds.c                     | 15 +++-
>  target/arm/common-semi-target.c               | 23 ++++--
>  target/arm/meson.build                        |  7 +-
>  target/i386/arch_dump.c                       |  8 +-
>  target/i386/cpu-system.c                      | 12 ++-
>  target/i386/cpu.c                             |  6 +-
>  target/loongarch/arch_dump.c                  |  8 +-
>  target/loongarch/loongarch-qmp-cmds.c         | 15 +++-
>  target/mips/system/mips-qmp-cmds.c            | 15 ++--
>  target/ppc/arch_dump.c                        |  8 +-
>  target/ppc/ppc-qmp-cmds.c                     | 15 ++--
>  target/riscv/arch_dump.c                      |  8 +-
>  target/riscv/common-semi-target.c             | 25 ++++--
>  target/riscv/helper.h                         |  6 +-
>  target/riscv/meson.build                      |  4 +-
>  target/riscv/riscv-qmp-cmds.c                 | 15 +++-
>  target/riscv/tcg/bitmanip_helper.c            |  4 +-
>  .../tcg/insn_trans/trans_privileged.c.inc     |  2 +-
>  target/riscv/tcg/insn_trans/trans_xlrbr.c.inc |  4 +-
>  target/riscv/tcg/op_helper.c                  |  2 +-
>  target/s390x/arch_dump.c                      |  8 +-
>  target/s390x/cpu_models_system.c              | 15 +++-
>  tests/qtest/fuzz/fuzz.c                       |  2 +-
>  53 files changed, 562 insertions(+), 207 deletions(-)
>  delete mode 100644 stubs/dump.c
>  delete mode 100644 stubs/qmp-cpu.c
> 

This series iterates on v1, but still does not tackle filtering of
devices/cpus between the targets. This is a prerequisite before being to
mix multiple targets together.

I sent the following series to show how a full filtering would work, and
if it's a direction people here would be interested to follow:
https://lore.kernel.org/qemu-devel/20260828225901.367438-1-pierrick.bouvier@oss.qualcomm.com/T/#t

Regards,
Pierrick