All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
@ 2026-08-23 15:07 Yonggang Luo
  2026-08-23 15:07 ` [PATCH 01/12] accel: use a shared TYPE_ACCEL_CPU parent Yonggang Luo
                   ` (14 more replies)
  0 siblings, 15 replies; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

This series produces one qemu-system binary that can run ARM (32 and 64)
and RISC-V (32 and 64, little- and big-endian TargetInfo). 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 mc->alias after the selected target is
  applied.
- 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:

- Register target-info-<name>-le and -be from one system
  target-info-def.c unit, sharing arch fields. is_default follows
  TARGET_BIG_ENDIAN so riscv/arm stay LE and ppc/s390x stay BE when
  -target is omitted.
- Parse -target before TargetInfo is fixed. Tokens are target_name or
  target_name-be / -le. When -target is omitted, infer the token from
  the program basename (strip .exe, longest registered suffix, drop a
  trailing w for Windows GUI binaries).
- 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 builds qemu-system (and qemu-systemw on Windows) from
aarch64 common/system objects plus RISC-V arch objects, and installs
qemu-system-{arm,aarch64,riscv32,riscv64} as symlinks so argv[0] still
selects TargetInfo.

Examples:

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

A basename that matches no registered token falls through to the unique
default. A combined binary with no suffix requires -target when more
than one default TargetInfo is registered.

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

Yonggang Luo (12):
  accel: use a shared TYPE_ACCEL_CPU parent
  hw/riscv/virt: use unique QOM name and target filter
  hw/arm/virt: use unique QOM name and target filter
  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
  target/riscv: seed cfg.big_endian from TargetInfo
  target-info: register le and be TargetInfo variants
  target-info: add -target and program-name selection
  target-info: dispatch CPU QMP, dump, and Angel semihosting
  meson: link ARM and RISC-V into qemu-system

 MAINTAINERS                                   |   1 -
 accel/accel-common.c                          |  21 +-
 hw/arm/virt-acpi-build.c                      |   4 +-
 hw/arm/virt.c                                 |  14 +-
 hw/core/cpu-system.c                          |  23 +++
 hw/core/machine-qmp-cmds.c                    |  26 +++
 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/loongarch/virt.h                   |   2 +-
 include/hw/riscv/virt.h                       |   6 +-
 include/qemu/target-info-impl.h               |   6 +
 include/qemu/target-info-init.h               |  29 ++-
 include/qemu/target-info-qom.h                |  51 ++++-
 include/semihosting/common-semi.h             |  56 +++++-
 meson.build                                   | 156 ++++++++++++++-
 qemu-options.hx                               |  13 ++
 stubs/dump.c                                  |  27 ---
 stubs/meson.build                             |   2 -
 stubs/qmp-cpu.c                               |  21 --
 system/vl.c                                   |  28 ++-
 target-info-def.c                             |  61 ++++--
 target-info-qom.c                             | 180 +++++++++++++++++-
 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/cpu.c                            |  10 +
 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, 809 insertions(+), 228 deletions(-)
 delete mode 100644 stubs/dump.c
 delete mode 100644 stubs/qmp-cpu.c

-- 
2.52.0.windows.1



^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 01/12] accel: use a shared TYPE_ACCEL_CPU parent
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
@ 2026-08-23 15:07 ` Yonggang Luo
  2026-08-23 15:07 ` [PATCH 02/12] hw/riscv/virt: use unique QOM name and target filter Yonggang Luo
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

- TYPE_ACCEL_CPU was "accel-" CPU_RESOLVING_TYPE, so each arch compiled
  a different parent (accel-arm-cpu, accel-riscv-cpu, ...). Common code
  registered only one of those names from target_cpu_type() at
  MODULE_INIT_QOM.
- A combined binary still registers every linked AccelCPU subclass.
  RISC-V tcg-accel-riscv-cpu has parent accel-riscv-cpu even when the
  selected target is ARM, so the old one-parent type_init does not
  cover the other family. Creating the parent in the subclass
  register path would hide that, but it keeps per-arch parents that
  AccelCPUClass does not need.
- AccelCPUClass is arch-independent. The parent only supplies
  class_size and ACCEL_CPU_CLASS(). Make TYPE_ACCEL_CPU the fixed
  abstract type accel-cpu and register it 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 (for example
  tcg-accel-arm-cpu). ACCEL_CPU_NAME() keeps that string; it is no
  longer derived from the parent type name.
- Drop register_accel_target_type(). Subclasses keep
  type_register_static() with .parent = TYPE_ACCEL_CPU.

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 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;
 
-- 
2.52.0.windows.1



^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH 02/12] hw/riscv/virt: use unique QOM name and target filter
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
  2026-08-23 15:07 ` [PATCH 01/12] accel: use a shared TYPE_ACCEL_CPU parent Yonggang Luo
@ 2026-08-23 15:07 ` Yonggang Luo
  2026-08-23 15:07 ` [PATCH 03/12] hw/arm/virt: " Yonggang Luo
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

- Set TYPE_RISCV_VIRT_MACHINE to MACHINE_TYPE_NAME("riscv-virt") so
  RISC-V virt no longer collides with ARM virt-machine in one process.
- Register TYPE_TARGET_SPECIFIC with is_available = target_base_riscv.
- Keep -machine virt via mc->alias after the selected target is applied.

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 hw/riscv/virt.c         | 6 +++++-
 include/hw/riscv/virt.h | 2 +-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 2d242ef71a5..1b672b2169d 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -22,6 +22,7 @@
 #include "qemu/units.h"
 #include "qemu/error-report.h"
 #include "qemu/guest-random.h"
+#include "qemu/target-info.h"
 #include "qapi/error.h"
 #include "hw/core/boards.h"
 #include "hw/core/loader.h"
@@ -1718,7 +1719,9 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
     MachineClass *mc = MACHINE_CLASS(oc);
     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
 
+    TARGET_SPECIFIC_CLASS(oc)->is_available = target_base_riscv;
     mc->desc = "RISC-V VirtIO board";
+    mc->alias = "virt";
     mc->init = virt_machine_init;
     mc->max_cpus = VIRT_CPUS_MAX;
     mc->default_cpu_type = TYPE_RISCV_CPU_BASE;
@@ -1782,7 +1785,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
 }
 
 static const TypeInfo virt_machine_typeinfo = {
-    .name       = MACHINE_TYPE_NAME("virt"),
+    .name       = TYPE_RISCV_VIRT_MACHINE,
     .parent     = TYPE_MACHINE,
     .class_init = virt_machine_class_init,
     .instance_init = virt_machine_instance_init,
@@ -1790,6 +1793,7 @@ static const TypeInfo virt_machine_typeinfo = {
     .instance_size = sizeof(RISCVVirtState),
     .interfaces = (const InterfaceInfo[]) {
          { TYPE_HOTPLUG_HANDLER },
+         { TYPE_TARGET_SPECIFIC },
          { }
     },
 };
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 36a2def4109..5559783aebb 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -30,7 +30,7 @@
 #define VIRT_SOCKETS_MAX_BITS          2
 #define VIRT_SOCKETS_MAX               (1 << VIRT_SOCKETS_MAX_BITS)
 
-#define TYPE_RISCV_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
+#define TYPE_RISCV_VIRT_MACHINE MACHINE_TYPE_NAME("riscv-virt")
 typedef struct RISCVVirtState RISCVVirtState;
 DECLARE_INSTANCE_CHECKER(RISCVVirtState, RISCV_VIRT_MACHINE,
                          TYPE_RISCV_VIRT_MACHINE)
-- 
2.52.0.windows.1



^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH 03/12] hw/arm/virt: use unique QOM name and target filter
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
  2026-08-23 15:07 ` [PATCH 01/12] accel: use a shared TYPE_ACCEL_CPU parent Yonggang Luo
  2026-08-23 15:07 ` [PATCH 02/12] hw/riscv/virt: use unique QOM name and target filter Yonggang Luo
@ 2026-08-23 15:07 ` Yonggang Luo
  2026-08-26 12:49   ` Daniel P. Berrangé
  2026-08-23 15:07 ` [PATCH 04/12] hw/arm/virt: prefix ACPI helpers with arm_virt_ Yonggang Luo
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

- Set TYPE_VIRT_MACHINE to MACHINE_TYPE_NAME("arm-virt") so ARM virt
  no longer collides with other virt-machine types in one process.
- Register TYPE_TARGET_SPECIFIC with is_available = target_base_arm on
  the abstract parent.
- Keep -machine virt via mc->alias on the latest versioned machine.

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 hw/arm/virt.c         | 2 ++
 include/hw/arm/virt.h | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index daba9af79f1..c2ace7706f1 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -4161,6 +4161,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
     MachineClass *mc = MACHINE_CLASS(oc);
     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
 
+    TARGET_SPECIFIC_CLASS(oc)->is_available = target_base_arm;
     mc->init = machvirt_init;
     /* Start with max_cpus set to 512, which is the maximum supported by KVM.
      * The value may be reduced later when we have more information about the
@@ -4431,6 +4432,7 @@ static const TypeInfo virt_machine_info = {
     .instance_finalize = virt_instance_finalize,
     .interfaces = (const InterfaceInfo[]) {
          { TYPE_HOTPLUG_HANDLER },
+         { TYPE_TARGET_SPECIFIC },
          { }
     },
 };
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 22e66d1a113..383ee320948 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -215,7 +215,7 @@ struct VirtMachineState {
 
 #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
 
-#define TYPE_VIRT_MACHINE   MACHINE_TYPE_NAME("virt")
+#define TYPE_VIRT_MACHINE   MACHINE_TYPE_NAME("arm-virt")
 OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE)
 
 void virt_acpi_setup(VirtMachineState *vms);
-- 
2.52.0.windows.1



^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH 04/12] hw/arm/virt: prefix ACPI helpers with arm_virt_
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (2 preceding siblings ...)
  2026-08-23 15:07 ` [PATCH 03/12] hw/arm/virt: " Yonggang Luo
@ 2026-08-23 15:07 ` Yonggang Luo
  2026-08-24  7:18   ` Philippe Mathieu-Daudé
  2026-08-23 15:07 ` [PATCH 05/12] hw/riscv/virt: prefix ACPI helpers with riscv_virt_ Yonggang Luo
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

- virt_acpi_setup and virt_is_acpi_enabled are generic names also used
  by RISC-V and LoongArch virt. A combined binary cannot export two
  functions with the same C symbol.
- Rename the ARM helpers to arm_virt_acpi_setup and
  arm_virt_is_acpi_enabled. Leave the trace event virt_acpi_setup
  unchanged; it is a separate identifier.

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 hw/arm/virt-acpi-build.c |  4 ++--
 hw/arm/virt.c            | 12 ++++++------
 include/hw/arm/virt.h    |  4 ++--
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index f6386088b6f..a4a0d2c9997 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -1556,7 +1556,7 @@ static const VMStateDescription vmstate_virt_acpi_build = {
     },
 };
 
-void virt_acpi_setup(VirtMachineState *vms)
+void arm_virt_acpi_setup(VirtMachineState *vms)
 {
     AcpiBuildTables tables;
     AcpiBuildState *build_state;
@@ -1567,7 +1567,7 @@ void virt_acpi_setup(VirtMachineState *vms)
         return;
     }
 
-    if (!virt_is_acpi_enabled(vms)) {
+    if (!arm_virt_is_acpi_enabled(vms)) {
         trace_virt_acpi_setup();
         return;
     }
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index c2ace7706f1..4b9e1e50d44 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -770,7 +770,7 @@ static void fdt_add_cpu_nodes(VirtMachineState *vms)
                     &bottom_node,
                     CPU_TOPOLOGY_LEVEL_SOCKET);
             if (cache_at_topo_level) {
-                if (bottom_node == 1 && !virt_is_acpi_enabled(vms))
+                if (bottom_node == 1 && !arm_virt_is_acpi_enabled(vms))
                     error_setg(
                         &error_fatal,
                         "Cannot share L1 at socket_id %d."
@@ -810,7 +810,7 @@ static void fdt_add_cpu_nodes(VirtMachineState *vms)
                                                         top_cluster,
                                                         bottom_cluster, cpu,
                                                         &cluster_offset);
-                if (bottom_cluster == 1 && !virt_is_acpi_enabled(vms)) {
+                if (bottom_cluster == 1 && !arm_virt_is_acpi_enabled(vms)) {
                     error_setg(&error_fatal,
                         "Cannot share L1 at socket_id %d, cluster_id %d. "
                         "DT limitation on sharing at cache level = 1.",
@@ -2037,7 +2037,7 @@ static void create_smmuv3_dev_dtb(VirtMachineState *vms, DeviceState *dev,
     hwaddr base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
     MachineState *ms = MACHINE(vms);
 
-    if (!(vms->bootinfo.firmware_loaded && virt_is_acpi_enabled(vms))) {
+    if (!(vms->bootinfo.firmware_loaded && arm_virt_is_acpi_enabled(vms))) {
         if (object_property_get_bool(OBJECT(dev), "accel", &error_abort)) {
             error_setg(errp, "SMMUv3 with accel=on not supported for DT");
             return;
@@ -2447,7 +2447,7 @@ void virt_machine_done(Notifier *notifier, void *data)
     pci_bus_add_fw_cfg_extra_pci_roots(vms->fw_cfg, vms->bus,
                                        &error_abort);
 
-    virt_acpi_setup(vms);
+    arm_virt_acpi_setup(vms);
     virt_build_smbios(vms);
 }
 
@@ -3211,7 +3211,7 @@ static void machvirt_init(MachineState *machine)
     create_pcie(vms);
     create_cxl_host_reg_region(vms);
 
-    if (aarch64 && firmware_loaded && virt_is_acpi_enabled(vms)) {
+    if (aarch64 && firmware_loaded && arm_virt_is_acpi_enabled(vms)) {
         vms->acpi_dev = create_acpi_ged(vms);
         vms->generic_error_notifier.notify = virt_generic_error_req;
         notifier_list_add(&acpi_generic_error_notifiers,
@@ -3561,7 +3561,7 @@ static void virt_set_oem_table_id(Object *obj, const char *value,
 }
 
 
-bool virt_is_acpi_enabled(const VirtMachineState *vms)
+bool arm_virt_is_acpi_enabled(const VirtMachineState *vms)
 {
     if (vms->acpi == ON_OFF_AUTO_OFF) {
         return false;
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 383ee320948..2ee61cc5a06 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -218,8 +218,8 @@ struct VirtMachineState {
 #define TYPE_VIRT_MACHINE   MACHINE_TYPE_NAME("arm-virt")
 OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE)
 
-void virt_acpi_setup(VirtMachineState *vms);
-bool virt_is_acpi_enabled(const VirtMachineState *vms);
+void arm_virt_acpi_setup(VirtMachineState *vms);
+bool arm_virt_is_acpi_enabled(const VirtMachineState *vms);
 
 #define CLIDR_CTYPE_NO_CACHE 0x00
 #define CLIDR_CTYPE_I_CACHE 0x01
-- 
2.52.0.windows.1



^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH 05/12] hw/riscv/virt: prefix ACPI helpers with riscv_virt_
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (3 preceding siblings ...)
  2026-08-23 15:07 ` [PATCH 04/12] hw/arm/virt: prefix ACPI helpers with arm_virt_ Yonggang Luo
@ 2026-08-23 15:07 ` Yonggang Luo
  2026-08-24  7:19   ` Philippe Mathieu-Daudé
  2026-08-23 15:07 ` [PATCH 06/12] hw/loongarch/virt: prefix ACPI helper with loongarch_virt_ Yonggang Luo
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

- virt_acpi_setup and virt_is_acpi_enabled collide with ARM virt when
  both architectures are linked into one qemu-system binary.
- Rename the RISC-V helpers to riscv_virt_acpi_setup and
  riscv_virt_is_acpi_enabled. Leave file-local virt_acpi_build* names
  unchanged.

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 hw/riscv/virt-acpi-build.c | 2 +-
 hw/riscv/virt.c            | 6 +++---
 include/hw/riscv/virt.h    | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 59c454f4f94..832261391d5 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -1017,7 +1017,7 @@ static const VMStateDescription vmstate_virt_acpi_build = {
     },
 };
 
-void virt_acpi_setup(RISCVVirtState *s)
+void riscv_virt_acpi_setup(RISCVVirtState *s)
 {
     AcpiBuildTables tables;
     AcpiBuildState *build_state;
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 1b672b2169d..16edad64f60 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1293,8 +1293,8 @@ static void virt_machine_done(Notifier *notifier, void *data)
 
     virt_build_smbios(s);
 
-    if (virt_is_acpi_enabled(s)) {
-        virt_acpi_setup(s);
+    if (riscv_virt_is_acpi_enabled(s)) {
+        riscv_virt_acpi_setup(s);
     }
 }
 
@@ -1652,7 +1652,7 @@ static void virt_set_iommu_sys(Object *obj, Visitor *v, const char *name,
     visit_type_OnOffAuto(v, name, &s->iommu_sys, errp);
 }
 
-bool virt_is_acpi_enabled(RISCVVirtState *s)
+bool riscv_virt_is_acpi_enabled(RISCVVirtState *s)
 {
     return s->acpi != ON_OFF_AUTO_OFF;
 }
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 5559783aebb..38ad8b0097e 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -133,9 +133,9 @@ enum {
 #define FDT_APLIC_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + \
                                  1 + FDT_APLIC_INT_CELLS)
 
-bool virt_is_acpi_enabled(RISCVVirtState *s);
+bool riscv_virt_is_acpi_enabled(RISCVVirtState *s);
 bool virt_is_iommu_sys_enabled(RISCVVirtState *s);
-void virt_acpi_setup(RISCVVirtState *vms);
+void riscv_virt_acpi_setup(RISCVVirtState *vms);
 
 /*
  * The virt machine physical address space used by some of the devices
-- 
2.52.0.windows.1



^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH 06/12] hw/loongarch/virt: prefix ACPI helper with loongarch_virt_
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (4 preceding siblings ...)
  2026-08-23 15:07 ` [PATCH 05/12] hw/riscv/virt: prefix ACPI helpers with riscv_virt_ Yonggang Luo
@ 2026-08-23 15:07 ` Yonggang Luo
  2026-08-24  1:00   ` gaosong
  2026-08-24  7:20   ` Philippe Mathieu-Daudé
  2026-08-23 15:07 ` [PATCH 07/12] target/riscv: uniquify TCG crc32, crc32c, and wfi helper names Yonggang Luo
                   ` (8 subsequent siblings)
  14 siblings, 2 replies; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

- virt_acpi_setup is the same C symbol used by ARM and RISC-V virt.
  Rename it now so a later combined binary does not need meson -D
  prefixes for LoongArch.
- Rename the file-local virt_is_acpi_enabled to
  loongarch_virt_is_acpi_enabled to match.

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 hw/loongarch/virt-acpi-build.c | 6 +++---
 hw/loongarch/virt.c            | 2 +-
 include/hw/loongarch/virt.h    | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/loongarch/virt-acpi-build.c b/hw/loongarch/virt-acpi-build.c
index a0b445f297b..bbbac289b49 100644
--- a/hw/loongarch/virt-acpi-build.c
+++ b/hw/loongarch/virt-acpi-build.c
@@ -674,7 +674,7 @@ static const VMStateDescription vmstate_acpi_build = {
     },
 };
 
-static bool virt_is_acpi_enabled(LoongArchVirtMachineState *lvms)
+static bool loongarch_virt_is_acpi_enabled(LoongArchVirtMachineState *lvms)
 {
     if (lvms->acpi == ON_OFF_AUTO_OFF) {
         return false;
@@ -682,7 +682,7 @@ static bool virt_is_acpi_enabled(LoongArchVirtMachineState *lvms)
     return true;
 }
 
-void virt_acpi_setup(LoongArchVirtMachineState *lvms)
+void loongarch_virt_acpi_setup(LoongArchVirtMachineState *lvms)
 {
     AcpiBuildTables tables;
     AcpiBuildState *build_state;
@@ -692,7 +692,7 @@ void virt_acpi_setup(LoongArchVirtMachineState *lvms)
         return;
     }
 
-    if (!virt_is_acpi_enabled(lvms)) {
+    if (!loongarch_virt_is_acpi_enabled(lvms)) {
         ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n");
         return;
     }
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 6693dea647b..74c9668b6e6 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -242,7 +242,7 @@ static void virt_done(Notifier *notifier, void *data)
     LoongArchVirtMachineState *lvms = container_of(notifier,
                                       LoongArchVirtMachineState, machine_done);
     virt_build_smbios(lvms);
-    virt_acpi_setup(lvms);
+    loongarch_virt_acpi_setup(lvms);
     virt_fdt_setup(lvms);
 }
 
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index d39a9bbf5dd..72268466def 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -132,7 +132,7 @@ struct LoongArchVirtMachineState {
 
 #define TYPE_LOONGARCH_VIRT_MACHINE  MACHINE_TYPE_NAME("virt")
 OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState, LOONGARCH_VIRT_MACHINE)
-void virt_acpi_setup(LoongArchVirtMachineState *lvms);
+void loongarch_virt_acpi_setup(LoongArchVirtMachineState *lvms);
 void virt_fdt_setup(LoongArchVirtMachineState *lvms);
 
 static inline bool virt_has_dmsi(LoongArchVirtMachineState *lvms)
-- 
2.52.0.windows.1



^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH 07/12] target/riscv: uniquify TCG crc32, crc32c, and wfi helper names
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (5 preceding siblings ...)
  2026-08-23 15:07 ` [PATCH 06/12] hw/loongarch/virt: prefix ACPI helper with loongarch_virt_ Yonggang Luo
@ 2026-08-23 15:07 ` Yonggang Luo
  2026-08-24  7:22   ` Philippe Mathieu-Daudé
  2026-08-23 15:07 ` [PATCH 08/12] target/riscv: seed cfg.big_endian from TargetInfo Yonggang Luo
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

- ARM already exports helper_crc32, helper_crc32c, helper_wfi, and the
  matching helper_info_* objects. RISC-V used the same DEF_HELPER names,
  which collide in a combined qemu-system link.
- Rename the RISC-V helpers to riscv_crc32, riscv_crc32c, and riscv_wfi
  so the generated C symbols are unique without meson -D prefixes.

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 target/riscv/helper.h                              | 6 +++---
 target/riscv/tcg/bitmanip_helper.c                 | 4 ++--
 target/riscv/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 +-
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 542b7c264fc..dd4623d2a79 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -84,8 +84,8 @@ DEF_HELPER_FLAGS_1(unzip, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(zip, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_2(xperm4, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 DEF_HELPER_FLAGS_2(xperm8, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(crc32, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_FLAGS_2(crc32c, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(riscv_crc32, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(riscv_crc32c, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 
 /* Floating Point - Half Precision */
 DEF_HELPER_FLAGS_3(fadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
@@ -135,7 +135,7 @@ DEF_HELPER_1(sret, tl, env)
 DEF_HELPER_1(mret, tl, env)
 DEF_HELPER_1(mnret, tl, env)
 DEF_HELPER_1(ctr_clear, void, env)
-DEF_HELPER_1(wfi, void, env)
+DEF_HELPER_1(riscv_wfi, void, env)
 DEF_HELPER_1(wrs_nto, void, env)
 DEF_HELPER_1(tlb_flush, void, env)
 DEF_HELPER_1(tlb_flush_all, void, env)
diff --git a/target/riscv/tcg/bitmanip_helper.c b/target/riscv/tcg/bitmanip_helper.c
index 1156a87dd31..18ad2fae1c9 100644
--- a/target/riscv/tcg/bitmanip_helper.c
+++ b/target/riscv/tcg/bitmanip_helper.c
@@ -132,7 +132,7 @@ target_ulong HELPER(xperm8)(target_ulong rs1, target_ulong rs2)
     return do_xperm(rs1, rs2, 3);
 }
 
-target_ulong HELPER(crc32)(target_ulong rs1, target_ulong sz)
+target_ulong HELPER(riscv_crc32)(target_ulong rs1, target_ulong sz)
 {
     for (target_ulong i = 0; i < sz; i++) {
         rs1 = crc32_table[rs1 & 0xFF] ^ (rs1 >> 8);
@@ -141,7 +141,7 @@ target_ulong HELPER(crc32)(target_ulong rs1, target_ulong sz)
     return rs1;
 }
 
-target_ulong HELPER(crc32c)(target_ulong rs1, target_ulong sz)
+target_ulong HELPER(riscv_crc32c)(target_ulong rs1, target_ulong sz)
 {
     for (target_ulong i = 0; i < sz; i++) {
         rs1 = crc32c_table[rs1 & 0xFF] ^ (rs1 >> 8);
diff --git a/target/riscv/tcg/insn_trans/trans_privileged.c.inc b/target/riscv/tcg/insn_trans/trans_privileged.c.inc
index a8eaccef67e..0df78e89745 100644
--- a/target/riscv/tcg/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/tcg/insn_trans/trans_privileged.c.inc
@@ -144,7 +144,7 @@ static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
 #ifndef CONFIG_USER_ONLY
     decode_save_opc(ctx, 0);
     gen_update_pc(ctx, ctx->cur_insn_len);
-    gen_helper_wfi(tcg_env);
+    gen_helper_riscv_wfi(tcg_env);
     return true;
 #else
     return false;
diff --git a/target/riscv/tcg/insn_trans/trans_xlrbr.c.inc b/target/riscv/tcg/insn_trans/trans_xlrbr.c.inc
index 01da2b6ce1d..795231f0839 100644
--- a/target/riscv/tcg/insn_trans/trans_xlrbr.c.inc
+++ b/target/riscv/tcg/insn_trans/trans_xlrbr.c.inc
@@ -29,11 +29,11 @@ static bool gen_crc(DisasContext *ctx, arg_r2 *a,
 #define TRANS_CRC32(NAME, SIZE) \
     static bool trans_crc32_##NAME(DisasContext *ctx, arg_r2 *a) \
     { if (SIZE == 8) { REQUIRE_64BIT(ctx); }; \
-      return gen_crc(ctx, a, gen_helper_crc32, tcg_constant_tl(SIZE)); }
+      return gen_crc(ctx, a, gen_helper_riscv_crc32, tcg_constant_tl(SIZE)); }
 #define TRANS_CRC32C(NAME, SIZE) \
     static bool trans_crc32c_##NAME(DisasContext *ctx, arg_r2 *a) \
     { if (SIZE == 8) { REQUIRE_64BIT(ctx); }; \
-      return gen_crc(ctx, a, gen_helper_crc32c, tcg_constant_tl(SIZE)); }
+      return gen_crc(ctx, a, gen_helper_riscv_crc32c, tcg_constant_tl(SIZE)); }
 
 TRANS_CRC32(b, 1);
 TRANS_CRC32(h, 2);
diff --git a/target/riscv/tcg/op_helper.c b/target/riscv/tcg/op_helper.c
index ba3c7da375a..52bcedc7c6e 100644
--- a/target/riscv/tcg/op_helper.c
+++ b/target/riscv/tcg/op_helper.c
@@ -541,7 +541,7 @@ void helper_ctr_clear(CPURISCVState *env)
     riscv_ctr_clear(env);
 }
 
-void helper_wfi(CPURISCVState *env)
+void HELPER(riscv_wfi)(CPURISCVState *env)
 {
     CPUState *cs = env_cpu(env);
     bool rvs = riscv_has_ext(env, RVS);
-- 
2.52.0.windows.1



^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH 08/12] target/riscv: seed cfg.big_endian from TargetInfo
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (6 preceding siblings ...)
  2026-08-23 15:07 ` [PATCH 07/12] target/riscv: uniquify TCG crc32, crc32c, and wfi helper names Yonggang Luo
@ 2026-08-23 15:07 ` Yonggang Luo
  2026-08-26 18:37   ` Philippe Mathieu-Daudé
  2026-08-23 15:07 ` [PATCH 09/12] target-info: register le and be TargetInfo variants Yonggang Luo
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

GDB register packets use target_big_endian() only (gdb_get_reg16/32/64).
RISC-V gdbstub already goes through those helpers, so future GDB
big-endian support does not need a second endian source in the CPU
gdbstub. It needs TargetInfo and the hart to agree.

Hart endian is cpu->cfg.big_endian, copied into mstatus MBE/SBE/UBE at
reset. The CPU property still defaults to little-endian, so a
big-endian TargetInfo would make GDB swap as BE while the hart stayed
LE.

- Initialize cfg.big_endian from target_big_endian() in cpu init so a
  big-endian TargetInfo also sets the hart.
- Fail realize when -cpu big-endian= disagrees with that selection.
  GDB cannot follow a per-CPU override, so a split would silently
  corrupt register byte order.

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 target/riscv/cpu.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5a82e6563bf..0681bec0bef 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -29,6 +29,7 @@
 #include "qapi/error.h"
 #include "qapi/visitor.h"
 #include "qemu/error-report.h"
+#include "qemu/target-info.h"
 #include "qemu/timer.h"
 #include "hw/core/qdev-properties.h"
 #include "hw/core/qdev-prop-internal.h"
@@ -1226,6 +1227,13 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
     Error *local_err = NULL;
 
+    if (cpu->cfg.big_endian != target_big_endian()) {
+        error_setg(errp,
+                   "CPU big-endian=%s does not match selected target endian",
+                   cpu->cfg.big_endian ? "on" : "off");
+        return;
+    }
+
     cpu_exec_realizefn(cs, &local_err);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
@@ -1407,6 +1415,8 @@ static void riscv_cpu_init(Object *obj)
     RISCVCPU *cpu = RISCV_CPU(obj);
     CPURISCVState *env = &cpu->env;
 
+    cpu->cfg.big_endian = target_big_endian();
+
     env->misa_mxl = mcc->def->misa_mxl_max;
 
 #ifndef CONFIG_USER_ONLY
-- 
2.52.0.windows.1



^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH 09/12] target-info: register le and be TargetInfo variants
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (7 preceding siblings ...)
  2026-08-23 15:07 ` [PATCH 08/12] target/riscv: seed cfg.big_endian from TargetInfo Yonggang Luo
@ 2026-08-23 15:07 ` Yonggang Luo
  2026-08-24 16:22   ` Pierrick Bouvier
  2026-08-23 15:07 ` [PATCH 10/12] target-info: add -target and program-name selection Yonggang Luo
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

- Register target-info-<name>-le and -be from one system
  target-info-def.c unit, sharing arch fields.
- Mark is_default from TARGET_BIG_ENDIAN so riscv/arm stay LE and
  ppc/s390x stay BE when -target is omitted.
- Pick the unique default in target_info_qom_set_target() when more
  than one TargetInfo is registered. Leave user-mode as a single
  target_info().

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 include/qemu/target-info-impl.h |  6 ++++
 include/qemu/target-info-init.h | 29 +++++++++++++---
 target-info-def.c               | 61 +++++++++++++++++++++++++--------
 target-info-qom.c               | 33 ++++++++++++++----
 4 files changed, 104 insertions(+), 25 deletions(-)

diff --git a/include/qemu/target-info-impl.h b/include/qemu/target-info-impl.h
index de329ec2b86..b4222e4455e 100644
--- a/include/qemu/target-info-impl.h
+++ b/include/qemu/target-info-impl.h
@@ -23,6 +23,12 @@ typedef struct TargetInfo {
     const char *cpu_type;
     /* related to TARGET_BIG_ENDIAN definition */
     EndianMode endianness;
+    /*
+     * True on the endian variant that matches this translation unit's
+     * TARGET_BIG_ENDIAN. target_info_qom_set_target() uses this when
+     * more than one TargetInfo is registered and -target is omitted.
+     */
+    bool is_default;
     /*
      * runtime equivalent of
      *   TARGET_PAGE_BITS_VARY ? TARGET_PAGE_BITS_LEGACY : TARGET_PAGE_BITS
diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h
index b7024c9faef..25d00adcc66 100644
--- a/include/qemu/target-info-init.h
+++ b/include/qemu/target-info-init.h
@@ -37,15 +37,34 @@ const TargetInfo *target_info(void)     \
 #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,                                \
+/*
+ * QOM type names are target-info-<TARGET_NAME>-le and -be so both
+ * endian variants can be registered from one system translation unit.
+ */
+#define TARGET_INFO_QOM_SUFFIX_0 "-le"
+#define TARGET_INFO_QOM_SUFFIX_1 "-be"
+
+#define TARGET_INFO_QOM_NAME(sel)                                           \
+    TYPE_TARGET_INFO "-" TARGET_NAME glue(TARGET_INFO_QOM_SUFFIX_, sel)
+
+#define TARGET_INFO_QOM_TYPEINFO(ti_var, sel)                               \
+static const TypeInfo glue(target_info_qom_type_, sel) = {                  \
+    .name = TARGET_INFO_QOM_NAME(sel),                                      \
     .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)
+}
+
+#define target_info_init_le_be(ti_le, ti_be)                                \
+TARGET_INFO_QOM_TYPEINFO(ti_le, 0);                                         \
+TARGET_INFO_QOM_TYPEINFO(ti_be, 1);                                         \
+static void do_qemu_init_target_info(void)                                  \
+{                                                                           \
+    type_register_static(&target_info_qom_type_0);                          \
+    type_register_static(&target_info_qom_type_1);                          \
+}                                                                           \
+module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO)
 
 #endif /* CONFIG_USER_ONLY */
 #endif /* COMPILING_PER_TARGET */
diff --git a/target-info-def.c b/target-info-def.c
index 5d38e405735..6722c43a08f 100644
--- a/target-info-def.c
+++ b/target-info-def.c
@@ -28,39 +28,72 @@ QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) != sizeof(CPUState));
 QEMU_BUILD_BUG_ON(TARGET_PAGE_BITS < TARGET_PAGE_BITS_MIN);
 #endif
 
-static const TargetInfo target_info_def = {
-    .target_name = TARGET_NAME,
-    .target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH),
-    .long_bits = TARGET_LONG_BITS,
-    .cpu_type = CPU_RESOLVING_TYPE,
-    .endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG : ENDIAN_MODE_LITTLE,
 #ifdef TARGET_PAGE_BITS_VARY
-    .page_bits_vary = true,
 # ifdef TARGET_PAGE_BITS_LEGACY
+#  define TARGET_INFO_PAGE_BITS \
+    .page_bits_vary = true, \
     .page_bits_init = TARGET_PAGE_BITS_LEGACY,
+# else
+#  define TARGET_INFO_PAGE_BITS \
+    .page_bits_vary = true,
 # endif
 #else
-    .page_bits_vary = false,
+# define TARGET_INFO_PAGE_BITS \
+    .page_bits_vary = false, \
     .page_bits_init = TARGET_PAGE_BITS,
 #endif
 
 #ifndef CONFIG_USER_ONLY
 # ifdef CONFIG_MULTIPROCESS
-    .config_multiprocess = true,
+#  define TARGET_INFO_CONFIG_MULTIPROCESS .config_multiprocess = true,
 # else
-    .config_multiprocess = false,
+#  define TARGET_INFO_CONFIG_MULTIPROCESS .config_multiprocess = false,
 # endif
 # ifdef CONFIG_NITRO
-    .config_nitro = true,
+#  define TARGET_INFO_CONFIG_NITRO .config_nitro = true,
 # else
-    .config_nitro = false,
+#  define TARGET_INFO_CONFIG_NITRO .config_nitro = false,
 # endif
 # ifdef CONFIG_XEN
-    .config_xen = true,
+#  define TARGET_INFO_CONFIG_XEN .config_xen = true,
 # else
-    .config_xen = false,
+#  define TARGET_INFO_CONFIG_XEN .config_xen = false,
 # endif
+# define TARGET_INFO_CONFIG \
+    TARGET_INFO_CONFIG_MULTIPROCESS \
+    TARGET_INFO_CONFIG_NITRO \
+    TARGET_INFO_CONFIG_XEN
+#else
+# define TARGET_INFO_CONFIG
 #endif
+
+#define TARGET_INFO_COMMON                                                  \
+    .target_name = TARGET_NAME,                                             \
+    .target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH),                      \
+    .long_bits = TARGET_LONG_BITS,                                          \
+    .cpu_type = CPU_RESOLVING_TYPE,                                         \
+    TARGET_INFO_PAGE_BITS                                                   \
+    TARGET_INFO_CONFIG
+
+#ifdef CONFIG_USER_ONLY
+static const TargetInfo target_info_def = {
+    TARGET_INFO_COMMON
+    .endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG : ENDIAN_MODE_LITTLE,
 };
 
 target_info_init(target_info_def)
+#else
+static const TargetInfo target_info_le = {
+    TARGET_INFO_COMMON
+    .endianness = ENDIAN_MODE_LITTLE,
+    .is_default = !TARGET_BIG_ENDIAN,
+};
+
+static const TargetInfo target_info_be = {
+    TARGET_INFO_COMMON
+    .endianness = ENDIAN_MODE_BIG,
+    .is_default = TARGET_BIG_ENDIAN,
+};
+
+target_info_init_le_be(target_info_le, target_info_be)
+#endif
diff --git a/target-info-qom.c b/target-info-qom.c
index 68ad734049c..2c1c57b05fd 100644
--- a/target-info-qom.c
+++ b/target-info-qom.c
@@ -90,13 +90,34 @@ const TargetInfo *target_info(void)
 void target_info_qom_set_target(void)
 {
     g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
-
+    const TargetInfo *chosen = NULL;
     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");
+    size_t num_default = 0;
+
+    if (num_found == 0) {
+        error_setg(&error_fatal, "no target-info is available");
+    }
+
+    if (num_found == 1) {
+        target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info;
+        return;
+    }
+
+    for (GSList *l = targets; l; l = l->next) {
+        const TargetInfo *ti = TARGET_INFO_CLASS(l->data)->target_info;
+
+        if (ti->is_default) {
+            num_default++;
+            chosen = ti;
+        }
+    }
+
+    if (num_default != 1) {
+        error_setg(&error_fatal, num_default == 0 ?
+                                 "no default target-info is available" :
+                                 "more than one default target-info "
+                                 "is available");
     }
 
-    target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info;
+    target_info_ptr = chosen;
 }
-- 
2.52.0.windows.1



^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH 10/12] target-info: add -target and program-name selection
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (8 preceding siblings ...)
  2026-08-23 15:07 ` [PATCH 09/12] target-info: register le and be TargetInfo variants Yonggang Luo
@ 2026-08-23 15:07 ` Yonggang Luo
  2026-08-24 16:24   ` Pierrick Bouvier
  2026-08-26 12:46   ` Daniel P. Berrangé
  2026-08-23 15:07 ` [PATCH 11/12] target-info: dispatch CPU QMP, dump, and Angel semihosting Yonggang Luo
                   ` (4 subsequent siblings)
  14 siblings, 2 replies; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

- Parse -target before TargetInfo is fixed; CLI overrides the program
  basename.
- Tokens are target_name or target_name-be / -le; -target help lists
  registered names in sorted order.
- When -target is omitted, infer the token from g_get_prgname(): strip
  .exe, take the longest dash-separated registered suffix, and retry
  without a trailing w for Windows GUI binaries.
- A basename that matches no registered token falls through to the
  unique default. Combined binaries with no suffix require -target
  when more than one default TargetInfo is registered.

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 include/qemu/target-info-qom.h |  10 +-
 qemu-options.hx                |  13 +++
 system/vl.c                    |  28 ++++--
 target-info-qom.c              | 167 ++++++++++++++++++++++++++++++---
 tests/qtest/fuzz/fuzz.c        |   2 +-
 5 files changed, 197 insertions(+), 23 deletions(-)

diff --git a/include/qemu/target-info-qom.h b/include/qemu/target-info-qom.h
index 842cf241e0a..3b59cf82d65 100644
--- a/include/qemu/target-info-qom.h
+++ b/include/qemu/target-info-qom.h
@@ -40,7 +40,15 @@ typedef struct TargetInfoQomClass {
 
 OBJECT_DECLARE_TYPE(TargetInfoQom, TargetInfoQomClass, TARGET_INFO)
 
-void target_info_qom_set_target(void);
+/**
+ * target_info_qom_set_target:
+ * @name: -target token, or NULL/%empty to infer from the program
+ * basename or the unique default
+ *
+ * Tokens are target_name (arch default endian) or target_name-be /
+ * target_name-le. -target overrides the program basename.
+ */
+void target_info_qom_set_target(const char *name);
 
 /**
  * get_machine_types_available:
diff --git a/qemu-options.hx b/qemu-options.hx
index 34970fffc94..638b531aa49 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -223,6 +223,19 @@ SRST
     as -machine.
 ERST
 
+DEF("target", HAS_ARG, QEMU_OPTION_target,
+    "-target name    select target ('-target help' for list)\n", QEMU_ARCH_ALL)
+SRST
+``-target name``
+    Select the emulation target (``-target help`` for the list). The
+    default endian is the architecture default (``riscv64`` is little
+    endian). The other endian uses a ``-be`` or ``-le`` suffix
+    (``riscv64-be``, ``ppc64-le``). If omitted, a matching suffix of
+    the program basename is used (``qemu-system-riscv64-be``, and
+    ``qemu-system-aarch64w.exe`` on Windows). ``-target`` overrides
+    the program name.
+ERST
+
 DEF("cpu", HAS_ARG, QEMU_OPTION_cpu,
     "-cpu cpu        select CPU ('-cpu help' for list)\n", QEMU_ARCH_ALL)
 SRST
diff --git a/system/vl.c b/system/vl.c
index 83b9425de9b..405f434e036 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -166,6 +166,7 @@ typedef struct DeviceOption {
     QTAILQ_ENTRY(DeviceOption) next;
 } DeviceOption;
 
+static const char *target_option;
 static const char *cpu_option;
 static const char *mem_path;
 static const char *incoming;
@@ -2899,19 +2900,12 @@ 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());
-
-    qemu_init_subsystems();
-
-    /* first pass of option parsing */
+    /*
+     * First pass: options needed before TargetInfo is fixed.
+     */
     optind = 1;
     while (optind < argc) {
         if (argv[optind][0] != '-') {
-            /* disk image */
             optind++;
         } else {
             const QEMUOption *popt;
@@ -2921,10 +2915,21 @@ void qemu_init(int argc, char **argv)
             case QEMU_OPTION_nouserconfig:
                 userconfig = false;
                 break;
+            case QEMU_OPTION_target:
+                target_option = optarg;
+                break;
             }
         }
     }
 
+    module_call_init(MODULE_INIT_TARGET_INFO);
+    target_info_qom_set_target(target_option);
+
+    module_init_info(qemu_modinfo);
+    module_allow_arch(target_name());
+
+    qemu_init_subsystems();
+
     machine_opts_dict = qdict_new();
     if (userconfig) {
         qemu_read_default_config_file(&error_fatal);
@@ -3687,6 +3692,9 @@ void qemu_init(int argc, char **argv)
             case QEMU_OPTION_nouserconfig:
                 /* Nothing to be parsed here. Especially, do not error out below. */
                 break;
+            case QEMU_OPTION_target:
+                /* Parsed before TargetInfo is selected. */
+                break;
 #if defined(CONFIG_POSIX) && !defined(EMSCRIPTEN)
             case QEMU_OPTION_daemonize:
                 os_set_daemonize(true);
diff --git a/target-info-qom.c b/target-info-qom.c
index 2c1c57b05fd..be03573a699 100644
--- a/target-info-qom.c
+++ b/target-info-qom.c
@@ -7,6 +7,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/help_option.h"
 #include "qapi/error.h"
 #include "qom/object.h"
 #include "qemu/target-info-impl.h"
@@ -87,7 +88,139 @@ const TargetInfo *target_info(void)
     return target_info_ptr;
 }
 
-void target_info_qom_set_target(void)
+static const TargetInfo *target_info_from_class(ObjectClass *oc)
+{
+    return TARGET_INFO_CLASS(oc)->target_info;
+}
+
+/* Default token is target_name; the other endian is target_name-le or -be. */
+static char *target_info_option_name(const TargetInfo *ti)
+{
+    if (ti->is_default) {
+        return g_strdup(ti->target_name);
+    }
+    if (ti->endianness == ENDIAN_MODE_BIG) {
+        return g_strdup_printf("%s-be", ti->target_name);
+    }
+    return g_strdup_printf("%s-le", ti->target_name);
+}
+
+static gint target_info_token_name_cmp(gconstpointer a, gconstpointer b,
+                                       gpointer data)
+{
+    const TargetInfo *ta = target_info_from_class((ObjectClass *)a);
+    const TargetInfo *tb = target_info_from_class((ObjectClass *)b);
+    g_autofree char *na = target_info_option_name(ta);
+    g_autofree char *nb = target_info_option_name(tb);
+
+    return strcmp(na, nb);
+}
+
+static void G_NORETURN target_info_list_and_exit(GSList *targets)
+{
+    printf("Supported targets:\n");
+    for (GSList *l = targets; l; l = l->next) {
+        const TargetInfo *ti = target_info_from_class(l->data);
+        g_autofree char *opt_name = target_info_option_name(ti);
+
+        printf("  %s%s\n", opt_name, ti->is_default ? " (default)" : "");
+    }
+    exit(0);
+}
+
+static const TargetInfo *target_info_find_default(GSList *targets,
+                                                  size_t *num_default)
+{
+    const TargetInfo *chosen = NULL;
+
+    *num_default = 0;
+    for (GSList *l = targets; l; l = l->next) {
+        const TargetInfo *ti = target_info_from_class(l->data);
+
+        if (ti->is_default) {
+            (*num_default)++;
+            chosen = ti;
+        }
+    }
+    return chosen;
+}
+
+static const TargetInfo *target_info_find_token(GSList *targets,
+                                                const char *token)
+{
+    for (GSList *l = targets; l; l = l->next) {
+        const TargetInfo *ti = target_info_from_class(l->data);
+        g_autofree char *opt_name = target_info_option_name(ti);
+
+        if (!strcmp(opt_name, token)) {
+            return ti;
+        }
+    }
+    return NULL;
+}
+
+static bool target_info_base_match_token(const char *base, const char *token)
+{
+    size_t nlen = strlen(token);
+    size_t blen;
+
+    if (!base || !token[0] || !g_str_has_suffix(base, token)) {
+        return false;
+    }
+    blen = strlen(base);
+    return blen == nlen || base[blen - nlen - 1] == '-';
+}
+
+static const TargetInfo *target_info_find_prgname(GSList *targets,
+                                                  const char *base)
+{
+    const TargetInfo *chosen = NULL;
+    size_t best_len = 0;
+
+    if (!base || !base[0]) {
+        return NULL;
+    }
+
+    for (GSList *l = targets; l; l = l->next) {
+        const TargetInfo *ti = target_info_from_class(l->data);
+        g_autofree char *opt_name = target_info_option_name(ti);
+        size_t nlen = strlen(opt_name);
+
+        if (nlen > best_len &&
+            target_info_base_match_token(base, opt_name)) {
+            chosen = ti;
+            best_len = nlen;
+        }
+    }
+    return chosen;
+}
+
+static const TargetInfo *target_info_from_prgname(GSList *targets)
+{
+    const char *prg = g_get_prgname();
+    g_autofree char *base = NULL;
+    char *dot;
+    const TargetInfo *chosen;
+
+    if (!prg || !prg[0]) {
+        return NULL;
+    }
+
+    base = g_path_get_basename(prg);
+    dot = strrchr(base, '.');
+    if (dot && g_ascii_strcasecmp(dot, ".exe") == 0) {
+        *dot = '\0';
+    }
+
+    chosen = target_info_find_prgname(targets, base);
+    if (!chosen && strlen(base) > 1 && g_str_has_suffix(base, "w")) {
+        base[strlen(base) - 1] = '\0';
+        chosen = target_info_find_prgname(targets, base);
+    }
+    return chosen;
+}
+
+void target_info_qom_set_target(const char *name)
 {
     g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
     const TargetInfo *chosen = NULL;
@@ -98,25 +231,37 @@ void target_info_qom_set_target(void)
         error_setg(&error_fatal, "no target-info is available");
     }
 
-    if (num_found == 1) {
-        target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info;
+    if (name && is_help_option(name)) {
+        targets = g_slist_sort_with_data(targets, target_info_token_name_cmp,
+                                         NULL);
+        target_info_list_and_exit(targets);
+    }
+
+    if (name && name[0]) {
+        chosen = target_info_find_token(targets, name);
+        if (!chosen) {
+            error_setg(&error_fatal, "unknown target '%s'", name);
+        }
+        target_info_ptr = chosen;
         return;
     }
 
-    for (GSList *l = targets; l; l = l->next) {
-        const TargetInfo *ti = TARGET_INFO_CLASS(l->data)->target_info;
+    chosen = target_info_from_prgname(targets);
+    if (chosen) {
+        target_info_ptr = chosen;
+        return;
+    }
 
-        if (ti->is_default) {
-            num_default++;
-            chosen = ti;
-        }
+    if (num_found == 1) {
+        target_info_ptr = target_info_from_class(targets->data);
+        return;
     }
 
+    chosen = target_info_find_default(targets, &num_default);
     if (num_default != 1) {
         error_setg(&error_fatal, num_default == 0 ?
                                  "no default target-info is available" :
-                                 "more than one default target-info "
-                                 "is available");
+                                 "multiple default targets; use -target");
     }
 
     target_info_ptr = chosen;
diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c
index a3a131c80f8..489c7138bb9 100644
--- a/tests/qtest/fuzz/fuzz.c
+++ b/tests/qtest/fuzz/fuzz.c
@@ -174,7 +174,7 @@ 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();
+    target_info_qom_set_target(NULL);
     module_call_init(MODULE_INIT_FUZZ_TARGET);
     module_call_init(MODULE_INIT_QOM);
     module_call_init(MODULE_INIT_LIBQOS);
-- 
2.52.0.windows.1



^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH 11/12] target-info: dispatch CPU QMP, dump, and Angel semihosting
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (9 preceding siblings ...)
  2026-08-23 15:07 ` [PATCH 10/12] target-info: add -target and program-name selection Yonggang Luo
@ 2026-08-23 15:07 ` Yonggang Luo
  2026-08-23 15:07 ` [PATCH 12/12] meson: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

- Combined binaries cannot keep one global C symbol per arch for
  query-cpu-definitions, dump notes, or Angel semihosting. Put those
  handlers on a process-wide TargetCpuOps table and fill one member
  at a time.
- TARGET_INFO_CPU_OP is type_init (MODULE_INIT_QOM). That runs after
  target_info_qom_set_target(), so ELF constructors only queue the
  callback. target_info_register_cpu_op() stores the impl only when
  cpu_type matches the selected TargetInfo; a duplicate slot is
  reported and ignored. A NULL member means this target has no
  handler, not "too early".
- Keep the table in target-info.c (common_ss) and filter with
  target_info()->cpu_type so user-mode can resolve TARGET_INFO_CPU_OP.
  Take the address of the impl so the same macro stores both function
  pointers and ops tables.
- QMP query-cpu-definitions and query-cpu-model-expansion dispatch
  from hw/core/machine-qmp-cmds.c. Dump cpu_get_dump_info and
  cpu_get_note_size dispatch from hw/core/cpu-system.c. Arch handlers
  are static with an arch prefix (s390_query_*, arm_get_dump_info,
  ...). ppc and mips drop expansion stubs; the dispatcher errors
  instead.
- Angel semihosting uses CPUSemihostingOps on TargetCpuOps.semihosting.
  ARM and RISC-V keep a static ops table in common-semi-target.c and
  register it with TARGET_INFO_CPU_OP. Wrappers in common-semi.h call
  target_info_cpu_ops()->semihosting. Always compile those files so
  both tables exist in a combined link.
- Drop stubs/qmp-cpu.c and stubs/dump.c: every system binary has the
  wrappers, and tools do not implement these commands. Keep
  stubs/qmp-cpu-s390x.c for comparison/baseline.

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 MAINTAINERS                           |  1 -
 hw/core/cpu-system.c                  | 23 +++++++++++
 hw/core/machine-qmp-cmds.c            | 26 +++++++++++++
 include/qemu/target-info-qom.h        | 41 ++++++++++++++++++++
 include/semihosting/common-semi.h     | 56 ++++++++++++++++++++++++---
 stubs/dump.c                          | 27 -------------
 stubs/meson.build                     |  2 -
 stubs/qmp-cpu.c                       | 21 ----------
 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/meson.build              |  4 +-
 target/riscv/riscv-qmp-cmds.c         | 15 +++++--
 target/s390x/arch_dump.c              |  8 +++-
 target/s390x/cpu_models_system.c      | 15 +++++--
 27 files changed, 313 insertions(+), 131 deletions(-)
 delete mode 100644 stubs/dump.c
 delete mode 100644 stubs/qmp-cpu.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 902db77218e..08e84e4ac6d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3348,7 +3348,6 @@ F: include/system/dump-arch.h
 F: include/system/dump.h
 F: qapi/dump.json
 F: scripts/dump-guest-memory.py
-F: stubs/dump.c
 F: docs/specs/vmcoreinfo.rst
 F: tests/qtest/vmcoreinfo-test.c
 F: tests/qtest/dump-test.c
diff --git a/hw/core/cpu-system.c b/hw/core/cpu-system.c
index 14eb4ed87f8..6dfbbac7f24 100644
--- a/hw/core/cpu-system.c
+++ b/hw/core/cpu-system.c
@@ -24,7 +24,9 @@
 #include "exec/cputlb.h"
 #include "exec/target_page.h"
 #include "system/memory.h"
+#include "system/dump-arch.h"
 #include "qemu/target-info.h"
+#include "qemu/target-info-qom.h"
 #include "hw/core/qdev.h"
 #include "hw/core/qdev-properties.h"
 #include "hw/core/sysemu-cpu-ops.h"
@@ -127,6 +129,27 @@ int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
     return (*cpu->cc->sysemu_ops->write_elf64_note)(f, cpu, cpuid, opaque);
 }
 
+int cpu_get_dump_info(ArchDumpInfo *info,
+                      const struct GuestPhysBlockList *guest_phys_blocks)
+{
+    const TargetCpuOps *ops = target_info_cpu_ops();
+
+    if (!ops->get_dump_info) {
+        return -1;
+    }
+    return ops->get_dump_info(info, guest_phys_blocks);
+}
+
+ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+{
+    const TargetCpuOps *ops = target_info_cpu_ops();
+
+    if (!ops->get_note_size) {
+        return -1;
+    }
+    return ops->get_note_size(class, machine, nr_cpus);
+}
+
 bool cpu_internal_is_big_endian(CPUState *cpu)
 {
     if (cpu->cc->sysemu_ops->internal_is_big_endian) {
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index e6e6ecc31e3..f8297203848 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -449,3 +449,29 @@ void qmp_dump_skeys(const char *filename, Error **errp)
     }
     DUMP_SKEYS_INTERFACE_CLASS(oc)->qmp_dump_skeys(filename, errp);
 }
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+    const TargetCpuOps *ops = target_info_cpu_ops();
+
+    if (!ops->query_cpu_definitions) {
+        error_setg(errp,
+                   "CPU model definitions are not supported on this target");
+        return NULL;
+    }
+    return ops->query_cpu_definitions(errp);
+}
+
+CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
+                                                     CpuModelInfo *model,
+                                                     Error **errp)
+{
+    const TargetCpuOps *ops = target_info_cpu_ops();
+
+    if (!ops->query_cpu_model_expansion) {
+        error_setg(errp,
+                   "CPU model expansion is not supported on this target");
+        return NULL;
+    }
+    return ops->query_cpu_model_expansion(type, model, errp);
+}
diff --git a/include/qemu/target-info-qom.h b/include/qemu/target-info-qom.h
index 3b59cf82d65..0f0f49faaa8 100644
--- a/include/qemu/target-info-qom.h
+++ b/include/qemu/target-info-qom.h
@@ -10,8 +10,12 @@
 #define QEMU_TARGET_INFO_QOM_H
 
 #include "qemu/target-info-impl.h"
+#include "qapi/error.h"
+#include "qemu/compiler.h"
 #include "qom/object.h"
 
+#include <stddef.h>
+
 #define TYPE_TARGET_INFO "target-info"
 
 #define TYPE_TARGET_SPECIFIC "target-specific"
@@ -40,6 +44,43 @@ typedef struct TargetInfoQomClass {
 
 OBJECT_DECLARE_TYPE(TargetInfoQom, TargetInfoQomClass, TARGET_INFO)
 
+typedef struct ArchDumpInfo ArchDumpInfo;
+struct GuestPhysBlockList;
+typedef struct CPUSemihostingOps CPUSemihostingOps;
+
+typedef struct TargetCpuOps {
+    CpuDefinitionInfoList *(*query_cpu_definitions)(Error **errp);
+    CpuModelExpansionInfo *(*query_cpu_model_expansion)(
+        CpuModelExpansionType type, CpuModelInfo *model, Error **errp);
+    int (*get_dump_info)(ArchDumpInfo *info,
+                         const struct GuestPhysBlockList *guest_phys_blocks);
+    ssize_t (*get_note_size)(int class, int machine, int nr_cpus);
+    const CPUSemihostingOps *semihosting;
+} TargetCpuOps;
+
+/**
+ * target_info_register_cpu_op:
+ * @cpu_type: CPU_RESOLVING_TYPE of the registering architecture
+ * @offset: offsetof(TargetCpuOps, member) for the slot being filled
+ * @impl: handler or ops table stored at that offset
+ *
+ * Combined binaries merge one member at a time so QMP, dump, and
+ * semihosting (or split QMP files) can register independently.
+ * MODULE_INIT_QOM runs after target_info_qom_set_target(), so only
+ * the selected cpu_type is stored.
+ */
+void target_info_register_cpu_op(const char *cpu_type, size_t offset,
+                                 void *impl);
+const TargetCpuOps *target_info_cpu_ops(void);
+
+#define TARGET_INFO_CPU_OP(cpu_type, member, impl)                            \
+static void glue(target_info_cpu_op_, impl)(void)                             \
+{                                                                             \
+    target_info_register_cpu_op((cpu_type), offsetof(TargetCpuOps, member),   \
+                                (void *)&(impl));                             \
+}                                                                             \
+type_init(glue(target_info_cpu_op_, impl))
+
 /**
  * target_info_qom_set_target:
  * @name: -target token, or NULL/%empty to infer from the program
diff --git a/include/semihosting/common-semi.h b/include/semihosting/common-semi.h
index aa511a46f42..f86a855a3dd 100644
--- a/include/semihosting/common-semi.h
+++ b/include/semihosting/common-semi.h
@@ -34,12 +34,56 @@
 #ifndef COMMON_SEMI_H
 #define COMMON_SEMI_H
 
+#include "exec/cpu-common.h"
+#include "qemu/target-info-qom.h"
+
+typedef struct CPUSemihostingOps {
+    uint64_t (*arg)(CPUState *cs, int argno);
+    void (*set_ret)(CPUState *cs, uint64_t ret);
+    bool (*is_64bit)(CPUArchState *env);
+    bool (*sys_exit_is_extended)(CPUState *cs);
+    uint64_t (*stack_bottom)(CPUState *cs);
+    bool (*has_synccache)(CPUArchState *env);
+} CPUSemihostingOps;
+
 void do_common_semihosting(CPUState *cs);
-uint64_t common_semi_arg(CPUState *cs, int argno);
-void common_semi_set_ret(CPUState *cs, uint64_t ret);
-bool is_64bit_semihosting(CPUArchState *env);
-bool common_semi_sys_exit_is_extended(CPUState *cs);
-uint64_t common_semi_stack_bottom(CPUState *cs);
-bool common_semi_has_synccache(CPUArchState *env);
+
+static inline const CPUSemihostingOps *cpu_semihosting_ops(void)
+{
+    const CPUSemihostingOps *ops = target_info_cpu_ops()->semihosting;
+
+    g_assert(ops);
+    return ops;
+}
+
+static inline uint64_t common_semi_arg(CPUState *cs, int argno)
+{
+    return cpu_semihosting_ops()->arg(cs, argno);
+}
+
+static inline void common_semi_set_ret(CPUState *cs, uint64_t ret)
+{
+    cpu_semihosting_ops()->set_ret(cs, ret);
+}
+
+static inline bool is_64bit_semihosting(CPUArchState *env)
+{
+    return cpu_semihosting_ops()->is_64bit(env);
+}
+
+static inline bool common_semi_sys_exit_is_extended(CPUState *cs)
+{
+    return cpu_semihosting_ops()->sys_exit_is_extended(cs);
+}
+
+static inline uint64_t common_semi_stack_bottom(CPUState *cs)
+{
+    return cpu_semihosting_ops()->stack_bottom(cs);
+}
+
+static inline bool common_semi_has_synccache(CPUArchState *env)
+{
+    return cpu_semihosting_ops()->has_synccache(env);
+}
 
 #endif /* COMMON_SEMI_H */
diff --git a/stubs/dump.c b/stubs/dump.c
deleted file mode 100644
index df7897b72b1..00000000000
--- a/stubs/dump.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * QEMU dump
- *
- * Copyright Fujitsu, Corp. 2011, 2012
- *
- * Authors:
- *     Wen Congyang <wency@cn.fujitsu.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "system/dump-arch.h"
-
-int cpu_get_dump_info(ArchDumpInfo *info,
-                      const struct GuestPhysBlockList *guest_phys_blocks)
-{
-    return -1;
-}
-
-ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
-{
-    return -1;
-}
-
diff --git a/stubs/meson.build b/stubs/meson.build
index 3b2f2680b19..94024aef868 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -68,7 +68,6 @@ if have_system
   # adding more of these.  If the symbol is used in specific_ss,
   # in particular, consider defining a preprocessor macro via
   # Kconfig or configs/targets/.
-  stub_ss.add(files('dump.c'))
   stub_ss.add(files('cmos.c'))
   stub_ss.add(files('fw_cfg.c'))
   if igvm.found()
@@ -82,7 +81,6 @@ if have_system
   stub_ss.add(files('qmp-i386-sev.c'))
   stub_ss.add(files('qmp-i386-sgx.c'))
   stub_ss.add(files('qmp-i386-xen.c'))
-  stub_ss.add(files('qmp-cpu.c'))
   stub_ss.add(files('qmp-cpu-s390x.c'))
   stub_ss.add(files('qmp-cpu-s390x-kvm.c'))
   stub_ss.add(files('hmp-cmd-info_mem.c'))
diff --git a/stubs/qmp-cpu.c b/stubs/qmp-cpu.c
deleted file mode 100644
index a8c7ee89b9d..00000000000
--- a/stubs/qmp-cpu.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qapi/qapi-commands-machine.h"
-
-CpuModelExpansionInfo *
-qmp_query_cpu_model_expansion(CpuModelExpansionType type,
-                              CpuModelInfo *model,
-                              Error **errp)
-{
-    error_setg(errp, "CPU model expansion is not supported on this target");
-    return NULL;
-}
-
-CpuDefinitionInfoList *
-qmp_query_cpu_definitions(Error **errp)
-{
-    error_setg(errp, "CPU model definitions are not supported on this target");
-    return NULL;
-}
diff --git a/target-info.c b/target-info.c
index ce7f9797dce..aa4be08bb94 100644
--- a/target-info.c
+++ b/target-info.c
@@ -7,9 +7,11 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
 #include "qemu/target-info.h"
 #include "qemu/target-info-qapi.h"
 #include "qemu/target-info-impl.h"
+#include "qemu/target-info-qom.h"
 #include "qapi/error.h"
 
 const char *target_name(void)
@@ -124,3 +126,33 @@ bool target_config_xen(void)
 {
     return target_info()->config_xen;
 }
+
+static TargetCpuOps target_cpu_ops;
+
+void target_info_register_cpu_op(const char *cpu_type, size_t offset,
+                                 void *impl)
+{
+    const TargetInfo *ti = target_info();
+    void **slot;
+
+    g_assert(ti);
+    g_assert(offset + sizeof(void *) <= sizeof(TargetCpuOps));
+    g_assert((offset % sizeof(void *)) == 0);
+
+    if (strcmp(cpu_type, ti->cpu_type)) {
+        return;
+    }
+
+    slot = (void **)((char *)&target_cpu_ops + offset);
+    if (*slot) {
+        error_report("TargetCpuOps already registered for type '%s' (offset %zu)",
+                     cpu_type, offset);
+        return;
+    }
+    *slot = impl;
+}
+
+const TargetCpuOps *target_info_cpu_ops(void)
+{
+    return &target_cpu_ops;
+}
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
index 1dd79849c13..e072516bdac 100644
--- a/target/arm/arch_dump.c
+++ b/target/arm/arch_dump.c
@@ -24,6 +24,7 @@
 #include "system/dump.h"
 #include "cpu-features.h"
 #include "internals.h"
+#include "qemu/target-info-qom.h"
 
 /* struct user_pt_regs from arch/arm64/include/uapi/asm/ptrace.h */
 struct aarch64_user_regs {
@@ -385,7 +386,7 @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
     return 0;
 }
 
-int cpu_get_dump_info(ArchDumpInfo *info,
+static int arm_get_dump_info(ArchDumpInfo *info,
                       const GuestPhysBlockList *guest_phys_blocks)
 {
     ARMCPU *cpu;
@@ -439,7 +440,7 @@ int cpu_get_dump_info(ArchDumpInfo *info,
     return 0;
 }
 
-ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+static ssize_t arm_get_note_size(int class, int machine, int nr_cpus)
 {
     ARMCPU *cpu = ARM_CPU(first_cpu);
     size_t note_size;
@@ -459,3 +460,6 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
 
     return note_size * nr_cpus;
 }
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_dump_info, arm_get_dump_info);
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_note_size, arm_get_note_size);
diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
index 83ec95c290f..c85bde5d79d 100644
--- a/target/arm/arm-qmp-cmds.c
+++ b/target/arm/arm-qmp-cmds.c
@@ -32,6 +32,7 @@
 #include "qobject/qdict.h"
 #include "qom/qom-qobject.h"
 #include "cpu.h"
+#include "qemu/target-info-qom.h"
 
 static GICCapability *gic_cap_new(int version)
 {
@@ -79,9 +80,10 @@ static const char *cpu_model_advertised_features[] = {
     NULL
 };
 
-CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
-                                                     CpuModelInfo *model,
-                                                     Error **errp)
+static CpuModelExpansionInfo *
+arm_query_cpu_model_expansion(CpuModelExpansionType type,
+                              CpuModelInfo *model,
+                              Error **errp)
 {
     CpuModelExpansionInfo *expansion_info;
     const QDict *qdict_in;
@@ -216,7 +218,7 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data)
     QAPI_LIST_PREPEND(*cpu_list, info);
 }
 
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+static CpuDefinitionInfoList *arm_query_cpu_definitions(Error **errp)
 {
     CpuDefinitionInfoList *cpu_list = NULL;
     GSList *list;
@@ -227,3 +229,8 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 
     return cpu_list;
 }
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions,
+                   arm_query_cpu_definitions);
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_model_expansion,
+                   arm_query_cpu_model_expansion);
diff --git a/target/arm/common-semi-target.c b/target/arm/common-semi-target.c
index 2b77ce9c17b..eccd3735df8 100644
--- a/target/arm/common-semi-target.c
+++ b/target/arm/common-semi-target.c
@@ -12,7 +12,7 @@
 #include "semihosting/common-semi.h"
 #include "target/arm/cpu-qom.h"
 
-uint64_t common_semi_arg(CPUState *cs, int argno)
+static uint64_t arm_common_semi_arg(CPUState *cs, int argno)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
@@ -23,7 +23,7 @@ uint64_t common_semi_arg(CPUState *cs, int argno)
     }
 }
 
-void common_semi_set_ret(CPUState *cs, uint64_t ret)
+static void arm_common_semi_set_ret(CPUState *cs, uint64_t ret)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
@@ -34,25 +34,36 @@ void common_semi_set_ret(CPUState *cs, uint64_t ret)
     }
 }
 
-bool common_semi_sys_exit_is_extended(CPUState *cs)
+static bool arm_common_semi_sys_exit_is_extended(CPUState *cs)
 {
     return is_a64(cpu_env(cs));
 }
 
-bool is_64bit_semihosting(CPUArchState *env)
+static bool arm_is_64bit_semihosting(CPUArchState *env)
 {
     return is_a64(env);
 }
 
-uint64_t common_semi_stack_bottom(CPUState *cs)
+static uint64_t arm_common_semi_stack_bottom(CPUState *cs)
 {
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
     return is_a64(env) ? env->xregs[31] : env->regs[13];
 }
 
-bool common_semi_has_synccache(CPUArchState *env)
+static bool arm_common_semi_has_synccache(CPUArchState *env)
 {
     /* Ok for A64, invalid for A32/T32 */
     return is_a64(env);
 }
+
+static const CPUSemihostingOps arm_semihosting_ops = {
+    .arg = arm_common_semi_arg,
+    .set_ret = arm_common_semi_set_ret,
+    .is_64bit = arm_is_64bit_semihosting,
+    .sys_exit_is_extended = arm_common_semi_sys_exit_is_extended,
+    .stack_bottom = arm_common_semi_stack_bottom,
+    .has_synccache = arm_common_semi_has_synccache,
+};
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, semihosting, arm_semihosting_ops);
diff --git a/target/arm/meson.build b/target/arm/meson.build
index 0369f96b4cc..dfcec55bd97 100644
--- a/target/arm/meson.build
+++ b/target/arm/meson.build
@@ -44,13 +44,10 @@ arm_stubs_ss.add(files(
 arm_user_ss.add(files(
   'el2-stubs.c',
   'cpregs-omap-stub.c',
+  'common-semi-target.c',
 ))
-arm_user_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING',
-		        if_true: files('common-semi-target.c'))
 
-arm_common_system_ss.add(files('cpu.c'))
-arm_common_system_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING',
-		                 if_true: files('common-semi-target.c'))
+arm_common_system_ss.add(files('cpu.c', 'common-semi-target.c'))
 arm_common_system_ss.add(files(
   'arch_dump.c',
   'arm-powerctl.c',
diff --git a/target/i386/arch_dump.c b/target/i386/arch_dump.c
index 16e47c4747d..c060b2b4ccb 100644
--- a/target/i386/arch_dump.c
+++ b/target/i386/arch_dump.c
@@ -16,6 +16,7 @@
 #include "system/dump.h"
 #include "elf.h"
 #include "system/memory_mapping.h"
+#include "qemu/target-info-qom.h"
 
 #define ELF_NOTE_SIZE(hdr_size, name_size, desc_size)   \
     ((DIV_ROUND_UP((hdr_size), 4)                       \
@@ -394,7 +395,7 @@ int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cs,
     return cpu_write_qemu_note(f, &cpu->env, s, 0);
 }
 
-int cpu_get_dump_info(ArchDumpInfo *info,
+static int x86_get_dump_info(ArchDumpInfo *info,
                       const GuestPhysBlockList *guest_phys_blocks)
 {
     bool lma = false;
@@ -429,7 +430,7 @@ int cpu_get_dump_info(ArchDumpInfo *info,
     return 0;
 }
 
-ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+static ssize_t x86_get_note_size(int class, int machine, int nr_cpus)
 {
     int name_size = 5; /* "CORE" or "QEMU" */
     size_t elf_note_size = 0;
@@ -459,3 +460,6 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
 
     return (elf_note_size + qemu_note_size) * nr_cpus;
 }
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_dump_info, x86_get_dump_info);
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_note_size, x86_get_note_size);
diff --git a/target/i386/cpu-system.c b/target/i386/cpu-system.c
index c8bbf0cbafd..d2babd1ba09 100644
--- a/target/i386/cpu-system.c
+++ b/target/i386/cpu-system.c
@@ -29,6 +29,7 @@
 #include "qapi/qapi-commands-machine.h"
 
 #include "cpu-internal.h"
+#include "qemu/target-info-qom.h"
 
 /* Return a QDict containing keys for all properties that can be included
  * in static expansion of CPU models. All properties set by x86_cpu_load_model()
@@ -188,10 +189,10 @@ out:
     return xc;
 }
 
-CpuModelExpansionInfo *
-qmp_query_cpu_model_expansion(CpuModelExpansionType type,
-                                                      CpuModelInfo *model,
-                                                      Error **errp)
+static CpuModelExpansionInfo *
+x86_query_cpu_model_expansion(CpuModelExpansionType type,
+                              CpuModelInfo *model,
+                              Error **errp)
 {
     X86CPU *xc = NULL;
     Error *err = NULL;
@@ -241,6 +242,9 @@ out:
     return ret;
 }
 
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_model_expansion,
+                   x86_query_cpu_model_expansion);
+
 void cpu_clear_apic_feature(CPUX86State *env)
 {
     env->features[FEAT_1_EDX] &= ~CPUID_APIC;
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5805d33ab92..4e31b8a2a60 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -48,6 +48,7 @@
 #include "system/address-spaces.h"
 #include "hw/core/boards.h"
 #include "hw/i386/sgx-epc.h"
+#include "qemu/target-info-qom.h"
 #endif
 #include "system/qtest.h"
 #include "tcg/tcg-cpu.h"
@@ -8191,7 +8192,7 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
     QAPI_LIST_PREPEND(*cpu_list, info);
 }
 
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+static CpuDefinitionInfoList *x86_query_cpu_definitions(Error **errp)
 {
     CpuDefinitionInfoList *cpu_list = NULL;
     GSList *list = get_sorted_cpu_model_list();
@@ -8200,6 +8201,9 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
     return cpu_list;
 }
 
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions,
+                   x86_query_cpu_definitions);
+
 #endif /* !CONFIG_USER_ONLY */
 
 static uint8_t x86_cpu_get_host_avx10_version(void)
diff --git a/target/loongarch/arch_dump.c b/target/loongarch/arch_dump.c
index 9d84faef969..af4ab5df5b5 100644
--- a/target/loongarch/arch_dump.c
+++ b/target/loongarch/arch_dump.c
@@ -22,6 +22,7 @@
 #include "elf.h"
 #include "system/dump.h"
 #include "internals.h"
+#include "qemu/target-info-qom.h"
 
 /* struct user_pt_regs from arch/loongarch/include/uapi/asm/ptrace.h */
 struct loongarch_user_regs {
@@ -142,7 +143,7 @@ int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
     return ret;
 }
 
-int cpu_get_dump_info(ArchDumpInfo *info,
+static int loongarch_get_dump_info(ArchDumpInfo *info,
                       const GuestPhysBlockList *guest_phys_blocks)
 {
     info->d_machine = EM_LOONGARCH;
@@ -152,7 +153,7 @@ int cpu_get_dump_info(ArchDumpInfo *info,
     return 0;
 }
 
-ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+static ssize_t loongarch_get_note_size(int class, int machine, int nr_cpus)
 {
     size_t note_size = 0;
 
@@ -162,3 +163,6 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
 
     return note_size * nr_cpus;
 }
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_dump_info, loongarch_get_dump_info);
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_note_size, loongarch_get_note_size);
diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c
index f053f22bb8c..848ad640aee 100644
--- a/target/loongarch/loongarch-qmp-cmds.c
+++ b/target/loongarch/loongarch-qmp-cmds.c
@@ -14,6 +14,7 @@
 #include "qobject/qdict.h"
 #include "qapi/qobject-input-visitor.h"
 #include "qom/qom-qobject.h"
+#include "qemu/target-info-qom.h"
 
 static void loongarch_cpu_add_definition(gpointer data, gpointer user_data)
 {
@@ -28,7 +29,7 @@ static void loongarch_cpu_add_definition(gpointer data, gpointer user_data)
     QAPI_LIST_PREPEND(*cpu_list, info);
 }
 
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+static CpuDefinitionInfoList *loongarch_query_cpu_definitions(Error **errp)
 {
     CpuDefinitionInfoList *cpu_list = NULL;
     GSList *list;
@@ -45,9 +46,10 @@ static const char *cpu_model_advertised_features[] = {
     "ptw", NULL
 };
 
-CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
-                                                     CpuModelInfo *model,
-                                                     Error **errp)
+static CpuModelExpansionInfo *
+loongarch_query_cpu_model_expansion(CpuModelExpansionType type,
+                                    CpuModelInfo *model,
+                                    Error **errp)
 {
     Visitor *visitor;
     CpuModelExpansionInfo *expansion_info;
@@ -133,3 +135,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 
     return expansion_info;
 }
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions,
+                   loongarch_query_cpu_definitions);
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_model_expansion,
+                   loongarch_query_cpu_model_expansion);
diff --git a/target/mips/system/mips-qmp-cmds.c b/target/mips/system/mips-qmp-cmds.c
index b6a2874f2dd..ff78487423b 100644
--- a/target/mips/system/mips-qmp-cmds.c
+++ b/target/mips/system/mips-qmp-cmds.c
@@ -11,15 +11,7 @@
 #include "qapi/error.h"
 #include "qapi/qapi-commands-machine.h"
 #include "cpu.h"
-
-CpuModelExpansionInfo *
-qmp_query_cpu_model_expansion(CpuModelExpansionType type,
-                              CpuModelInfo *model,
-                              Error **errp)
-{
-    error_setg(errp, "CPU model expansion is not supported on this target");
-    return NULL;
-}
+#include "qemu/target-info-qom.h"
 
 static void mips_cpu_add_definition(gpointer data, gpointer user_data)
 {
@@ -36,7 +28,7 @@ static void mips_cpu_add_definition(gpointer data, gpointer user_data)
     QAPI_LIST_PREPEND(*cpu_list, info);
 }
 
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+static CpuDefinitionInfoList *mips_query_cpu_definitions(Error **errp)
 {
     CpuDefinitionInfoList *cpu_list = NULL;
     GSList *list;
@@ -47,3 +39,6 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 
     return cpu_list;
 }
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions,
+                   mips_query_cpu_definitions);
diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
index 80ac6c3e320..07f0c75c45e 100644
--- a/target/ppc/arch_dump.c
+++ b/target/ppc/arch_dump.c
@@ -17,6 +17,7 @@
 #include "elf.h"
 #include "system/dump.h"
 #include "system/kvm.h"
+#include "qemu/target-info-qom.h"
 
 #ifdef TARGET_PPC64
 #define ELFCLASS ELFCLASS64
@@ -229,7 +230,7 @@ static const struct NoteFuncDescStruct {
 
 typedef struct NoteFuncDescStruct NoteFuncDesc;
 
-int cpu_get_dump_info(ArchDumpInfo *info,
+static int ppc_get_dump_info(ArchDumpInfo *info,
                       const struct GuestPhysBlockList *guest_phys_blocks)
 {
     PowerPCCPU *cpu;
@@ -257,7 +258,7 @@ int cpu_get_dump_info(ArchDumpInfo *info,
     return 0;
 }
 
-ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+static ssize_t ppc_get_note_size(int class, int machine, int nr_cpus)
 {
     int name_size = 8; /* "CORE" or "QEMU" rounded */
     size_t elf_note_size = 0;
@@ -313,3 +314,6 @@ int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     return ppc_write_all_elf_notes("CORE", f, cpu, cpuid, s);
 }
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_dump_info, ppc_get_dump_info);
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_note_size, ppc_get_note_size);
diff --git a/target/ppc/ppc-qmp-cmds.c b/target/ppc/ppc-qmp-cmds.c
index 96228919966..70fca0170b1 100644
--- a/target/ppc/ppc-qmp-cmds.c
+++ b/target/ppc/ppc-qmp-cmds.c
@@ -29,15 +29,7 @@
 #include "qapi/qapi-commands-machine.h"
 #include "cpu-models.h"
 #include "cpu-qom.h"
-
-CpuModelExpansionInfo *
-qmp_query_cpu_model_expansion(CpuModelExpansionType type,
-                              CpuModelInfo *model,
-                              Error **errp)
-{
-    error_setg(errp, "CPU model expansion is not supported on this target");
-    return NULL;
-}
+#include "qemu/target-info-qom.h"
 
 static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
 {
@@ -53,7 +45,7 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
     QAPI_LIST_PREPEND(*first, info);
 }
 
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+static CpuDefinitionInfoList *ppc_query_cpu_definitions(Error **errp)
 {
     CpuDefinitionInfoList *cpu_list = NULL;
     GSList *list;
@@ -82,3 +74,6 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 
     return cpu_list;
 }
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions,
+                   ppc_query_cpu_definitions);
diff --git a/target/riscv/arch_dump.c b/target/riscv/arch_dump.c
index 12b68799070..7e4b584faa0 100644
--- a/target/riscv/arch_dump.c
+++ b/target/riscv/arch_dump.c
@@ -20,6 +20,7 @@
 #include "cpu.h"
 #include "elf.h"
 #include "system/dump.h"
+#include "qemu/target-info-qom.h"
 
 /* struct user_regs_struct from arch/riscv/include/uapi/asm/ptrace.h */
 struct riscv64_user_regs {
@@ -161,7 +162,7 @@ int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
     return ret;
 }
 
-int cpu_get_dump_info(ArchDumpInfo *info,
+static int riscv_get_dump_info(ArchDumpInfo *info,
                       const GuestPhysBlockList *guest_phys_blocks)
 {
     RISCVCPU *cpu;
@@ -187,7 +188,7 @@ int cpu_get_dump_info(ArchDumpInfo *info,
     return 0;
 }
 
-ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+static ssize_t riscv_get_note_size(int class, int machine, int nr_cpus)
 {
     size_t note_size;
 
@@ -199,3 +200,6 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
 
     return note_size * nr_cpus;
 }
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_dump_info, riscv_get_dump_info);
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_note_size, riscv_get_note_size);
diff --git a/target/riscv/common-semi-target.c b/target/riscv/common-semi-target.c
index aeaeb88d536..aed9dfc5b68 100644
--- a/target/riscv/common-semi-target.c
+++ b/target/riscv/common-semi-target.c
@@ -12,38 +12,49 @@
 #include "cpu.h"
 #include "semihosting/common-semi.h"
 
-uint64_t common_semi_arg(CPUState *cs, int argno)
+static uint64_t riscv_common_semi_arg(CPUState *cs, int argno)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
     return env->gpr[xA0 + argno];
 }
 
-void common_semi_set_ret(CPUState *cs, uint64_t ret)
+static void riscv_common_semi_set_ret(CPUState *cs, uint64_t ret)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
     env->gpr[xA0] = ret;
 }
 
-bool is_64bit_semihosting(CPUArchState *env)
+static bool riscv_is_64bit_semihosting(CPUArchState *env)
 {
     return riscv_cpu_mxl(env) != MXL_RV32;
 }
 
-bool common_semi_sys_exit_is_extended(CPUState *cs)
+static bool riscv_common_semi_sys_exit_is_extended(CPUState *cs)
 {
-    return is_64bit_semihosting(cpu_env(cs));
+    return riscv_is_64bit_semihosting(cpu_env(cs));
 }
 
-uint64_t common_semi_stack_bottom(CPUState *cs)
+static uint64_t riscv_common_semi_stack_bottom(CPUState *cs)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
     return env->gpr[xSP];
 }
 
-bool common_semi_has_synccache(CPUArchState *env)
+static bool riscv_common_semi_has_synccache(CPUArchState *env)
 {
     return true;
 }
+
+static const CPUSemihostingOps riscv_semihosting_ops = {
+    .arg = riscv_common_semi_arg,
+    .set_ret = riscv_common_semi_set_ret,
+    .is_64bit = riscv_is_64bit_semihosting,
+    .sys_exit_is_extended = riscv_common_semi_sys_exit_is_extended,
+    .stack_bottom = riscv_common_semi_stack_bottom,
+    .has_synccache = riscv_common_semi_has_synccache,
+};
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, semihosting, riscv_semihosting_ops);
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 42d0f6d538a..5adb6d1c9e7 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -11,12 +11,10 @@ gen = [
 riscv_ss = ss.source_set()
 riscv_ss.add(gen)
 
-riscv_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING',
-		     if_true: files('common-semi-target.c'))
-
 riscv_ss.add(files(
   'cpu.c',
   'gdbstub.c',
+  'common-semi-target.c',
 ))
 
 riscv_system_ss = ss.source_set()
diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c
index 2647deef916..248e6a0eaf0 100644
--- a/target/riscv/riscv-qmp-cmds.c
+++ b/target/riscv/riscv-qmp-cmds.c
@@ -36,6 +36,7 @@
 #include "cpu-qom.h"
 #include "cpu.h"
 #include "target/riscv/tcg/csr.h"
+#include "qemu/target-info-qom.h"
 
 static void riscv_cpu_add_definition(gpointer data, gpointer user_data)
 {
@@ -54,7 +55,7 @@ static void riscv_cpu_add_definition(gpointer data, gpointer user_data)
     QAPI_LIST_PREPEND(*cpu_list, info);
 }
 
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+static CpuDefinitionInfoList *riscv_query_cpu_definitions(Error **errp)
 {
     CpuDefinitionInfoList *cpu_list = NULL;
     GSList *list = object_class_get_list(TYPE_RISCV_CPU, false);
@@ -154,9 +155,10 @@ err:
     visit_free(visitor);
 }
 
-CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
-                                                     CpuModelInfo *model,
-                                                     Error **errp)
+static CpuModelExpansionInfo *
+riscv_query_cpu_model_expansion(CpuModelExpansionType type,
+                                CpuModelInfo *model,
+                                Error **errp)
 {
     CpuModelExpansionInfo *expansion_info;
     QDict *qdict_out;
@@ -225,3 +227,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 
     return expansion_info;
 }
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions,
+                   riscv_query_cpu_definitions);
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_model_expansion,
+                   riscv_query_cpu_model_expansion);
diff --git a/target/s390x/arch_dump.c b/target/s390x/arch_dump.c
index 2c26e992959..c0334baa72f 100644
--- a/target/s390x/arch_dump.c
+++ b/target/s390x/arch_dump.c
@@ -18,6 +18,7 @@
 #include "elf.h"
 #include "system/dump.h"
 #include "kvm/kvm_s390x.h"
+#include "qemu/target-info-qom.h"
 #include "target/s390x/kvm/pv.h"
 
 struct S390xUserRegsStruct {
@@ -449,7 +450,7 @@ static void arch_cleanup(DumpState *s)
     }
 }
 
-int cpu_get_dump_info(ArchDumpInfo *info,
+static int s390_get_dump_info(ArchDumpInfo *info,
                       const struct GuestPhysBlockList *guest_phys_blocks)
 {
     info->d_machine = EM_S390;
@@ -469,7 +470,7 @@ int cpu_get_dump_info(ArchDumpInfo *info,
     return 0;
 }
 
-ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+static ssize_t s390_get_note_size(int class, int machine, int nr_cpus)
 {
     int name_size = 8; /* "LINUX" or "CORE" + pad */
     size_t elf_note_size = 0;
@@ -495,3 +496,6 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
 
     return (elf_note_size) * nr_cpus;
 }
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_dump_info, s390_get_dump_info);
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, get_note_size, s390_get_note_size);
diff --git a/target/s390x/cpu_models_system.c b/target/s390x/cpu_models_system.c
index 5b846048675..5470bf55e20 100644
--- a/target/s390x/cpu_models_system.c
+++ b/target/s390x/cpu_models_system.c
@@ -20,6 +20,7 @@
 #include "qapi/qobject-input-visitor.h"
 #include "qobject/qdict.h"
 #include "qapi/qapi-commands-machine.h"
+#include "qemu/target-info-qom.h"
 
 static void list_add_feat(const char *name, void *opaque);
 
@@ -82,7 +83,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
     QAPI_LIST_PREPEND(*cpu_list, info);
 }
 
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+static CpuDefinitionInfoList *s390_query_cpu_definitions(Error **errp)
 {
     struct CpuDefinitionInfoListData list_data = {
         .list = NULL,
@@ -208,9 +209,10 @@ static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
     }
 }
 
-CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
-                                                      CpuModelInfo *model,
-                                                      Error **errp)
+static CpuModelExpansionInfo *
+s390_query_cpu_model_expansion(CpuModelExpansionType type,
+                               CpuModelInfo *model,
+                               Error **errp)
 {
     Error *err = NULL;
     CpuModelExpansionInfo *expansion_info = NULL;
@@ -434,3 +436,8 @@ void apply_cpu_model(const S390CPUModel *model, Error **errp)
         applied_model = *model;
     }
 }
+
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_definitions,
+                   s390_query_cpu_definitions);
+TARGET_INFO_CPU_OP(CPU_RESOLVING_TYPE, query_cpu_model_expansion,
+                   s390_query_cpu_model_expansion);
-- 
2.52.0.windows.1



^ permalink raw reply related	[flat|nested] 57+ messages in thread

* [PATCH 12/12] meson: link ARM and RISC-V into qemu-system
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (10 preceding siblings ...)
  2026-08-23 15:07 ` [PATCH 11/12] target-info: dispatch CPU QMP, dump, and Angel semihosting Yonggang Luo
@ 2026-08-23 15:07 ` Yonggang Luo
  2026-08-24 16:20   ` Pierrick Bouvier
  2026-08-24 16:36 ` [PATCH 00/12] single-binary: " Pierrick Bouvier
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 57+ messages in thread
From: Yonggang Luo @ 2026-08-23 15:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

- Build qemu-system (and qemu-systemw on Windows) from aarch64
  common/system objects plus RISC-V arch objects taken from the
  existing riscv64 lib.
- Pull 32-bit TargetInfo and 32-only boards from the arm/riscv32
  libs so hw/arm and target/riscv are not compiled twice.
- Skip linking qemu-system-{arm,aarch64,riscv32,riscv64} and the
  Windows *w variants; symlink those names to qemu-system so
  argv[0] still selects TargetInfo.

Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 meson.build | 156 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 147 insertions(+), 9 deletions(-)

diff --git a/meson.build b/meson.build
index 449d50f2983..b4f435f6a22 100644
--- a/meson.build
+++ b/meson.build
@@ -4250,6 +4250,10 @@ endif
 
 traceable = []
 emulators = {}
+target_softmmu = {}
+combo_softmmu = ['aarch64-softmmu', 'arm-softmmu', 'riscv32-softmmu', 'riscv64-softmmu']
+have_qemu_system_combo = ('aarch64-softmmu' in target_dirs
+                          and 'riscv64-softmmu' in target_dirs)
 foreach target : target_dirs
   config_target = config_target_mak[target]
   target_name = config_target['TARGET_NAME']
@@ -4399,20 +4403,37 @@ foreach target : target_dirs
                  c_args: c_args,
                  build_by_default: false)
 
+  if target in combo_softmmu
+    target_softmmu += {target: {
+      'lib': lib,
+      'arch_srcs': arch_srcs,
+      'arch_deps': arch_deps,
+      'c_args': c_args,
+      'link_args': link_args,
+      'target_stubs': target_stubs,
+      'main_rs': main_rs,
+      'config_target': config_target,
+      'target_base_arch': target_base_arch,
+    }}
+  endif
+
   if target.endswith('-softmmu')
-    execs = [{
-      'name': 'qemu-system-' + target_name,
-      'win_subsystem': 'console',
-      'sources': [main_rs, files('system/main.c')],
-      'dependencies': [sdl, target_stubs],
-    }]
-    if host_os == 'windows' and (sdl.found() or gtk.found())
+    execs = []
+    if not (have_qemu_system_combo and target in combo_softmmu)
       execs += [{
-        'name': 'qemu-system-' + target_name + 'w',
-        'win_subsystem': 'windows',
+        'name': 'qemu-system-' + target_name,
+        'win_subsystem': 'console',
         'sources': [main_rs, files('system/main.c')],
         'dependencies': [sdl, target_stubs],
       }]
+      if host_os == 'windows' and (sdl.found() or gtk.found())
+        execs += [{
+          'name': 'qemu-system-' + target_name + 'w',
+          'win_subsystem': 'windows',
+          'sources': [main_rs, files('system/main.c')],
+          'dependencies': [sdl, target_stubs],
+        }]
+      endif
     endif
     if get_option('fuzzing')
       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
@@ -4481,6 +4502,123 @@ foreach target : target_dirs
   endforeach
 endforeach
 
+# Combined ARM + RISC-V system emulator (32 and 64).
+# Common/system objects come from aarch64. RISC-V arch objects come
+# from the existing riscv64 lib. 32-bit TargetInfo and 32-only boards
+# come from the arm/riscv32 libs. Per-target qemu-system-* names are
+# symlinks to qemu-system (argv[0] selects TargetInfo).
+if have_qemu_system_combo
+  a64 = target_softmmu['aarch64-softmmu']
+  rv = target_softmmu['riscv64-softmmu']
+  extra_objs = []
+  target_info_def = files('target-info-def.c')
+  foreach spec : [[common_ss, common_all], [system_ss, libsystem]]
+    rv_src = spec[0].apply(rv['config_target'], strict: false)
+    a64_src = spec[0].apply(a64['config_target'], strict: false)
+    extra = []
+    foreach f : rv_src.sources()
+      if f not in a64_src.sources() and not f.full_path().endswith('_stubs.c')
+        extra += f
+      endif
+    endforeach
+    if extra.length() > 0
+      extra_objs += spec[1].extract_objects(extra)
+    endif
+  endforeach
+  rv_base = rv['target_base_arch']
+  if rv_base in target_common_arch_libs
+    src = target_common_arch[rv_base].apply(rv['config_target'], strict: false)
+    extra_objs += target_common_arch_libs[rv_base].extract_objects(src.sources())
+  endif
+  if rv_base in target_common_system_arch_libs
+    src = target_common_system_arch[rv_base].apply(rv['config_target'], strict: false)
+    extra_objs += target_common_system_arch_libs[rv_base].extract_objects(src.sources())
+  endif
+  foreach pair : [['arm-softmmu', 'aarch64-softmmu'], ['riscv32-softmmu', 'riscv64-softmmu']]
+    t32 = pair[0]
+    t64 = pair[1]
+    if t32 in target_softmmu
+      extra_objs += target_softmmu[t32]['lib'].extract_objects(target_info_def)
+      base32 = target_softmmu[t32]['target_base_arch']
+      if base32 in hw_arch
+        hw32 = hw_arch[base32].apply(target_softmmu[t32]['config_target'], strict: false)
+        hw64 = hw_arch[base32].apply(target_softmmu[t64]['config_target'], strict: false)
+        extra_hw = []
+        foreach f : hw32.sources()
+          if f not in hw64.sources()
+            extra_hw += f
+          endif
+        endforeach
+        if extra_hw.length() > 0
+          extra_objs += target_softmmu[t32]['lib'].extract_objects(extra_hw)
+        endif
+      endif
+    endif
+  endforeach
+  combo_objects = extra_objs
+  combo_objects += a64['lib'].extract_all_objects(recursive: true)
+  combo_objects += rv['lib'].extract_objects(rv['arch_srcs'])
+  combo_deps = a64['arch_deps'] + rv['arch_deps'] + [sdl, a64['target_stubs'], rv['target_stubs']]
+  if 'arm-softmmu' in target_softmmu
+    combo_deps += target_softmmu['arm-softmmu']['arch_deps']
+  endif
+  if 'riscv32-softmmu' in target_softmmu
+    combo_deps += target_softmmu['riscv32-softmmu']['arch_deps']
+  endif
+  combo_execs = [{
+    'name': 'qemu-system',
+    'win_subsystem': 'console',
+  }]
+  if host_os == 'windows' and (sdl.found() or gtk.found())
+    combo_execs += [{
+      'name': 'qemu-systemw',
+      'win_subsystem': 'windows',
+    }]
+  endif
+  combo_exe_suffix = host_os == 'windows' ? '.exe' : ''
+  combo_alias_py = 'import os, sys; src, dst = sys.argv[1:3]; os.path.exists(dst) and os.remove(dst); os.symlink(os.path.basename(src), dst)'
+  foreach exe : combo_execs
+    emulator = executable(exe['name'], [a64['main_rs'], files('system/main.c')],
+               install: true,
+               c_args: a64['c_args'],
+               dependencies: combo_deps,
+               objects: combo_objects,
+               link_depends: [block_syms, qemu_syms],
+               link_args: a64['link_args'],
+               win_subsystem: exe['win_subsystem'])
+    emulators += {exe['name']: emulator}
+    traceable += [{
+      'exe': exe['name'],
+      'probe-prefix': 'qemu.system.multi',
+    }]
+    foreach t : combo_softmmu
+      if t not in target_softmmu
+        continue
+      endif
+      tname = target_softmmu[t]['config_target']['TARGET_NAME']
+      if exe['name'] == 'qemu-systemw'
+        alias = 'qemu-system-' + tname + 'w'
+      else
+        alias = 'qemu-system-' + tname
+      endif
+      alias_tgt = custom_target(alias,
+                                input: emulator,
+                                output: alias + combo_exe_suffix,
+                                command: [python, '-c', combo_alias_py, '@INPUT@', '@OUTPUT@'],
+                                build_by_default: true,
+                                install: false)
+      emulators += {alias: alias_tgt}
+      install_symlink(alias + combo_exe_suffix,
+                      pointing_to: exe['name'] + combo_exe_suffix,
+                      install_dir: get_option('bindir'))
+      traceable += [{
+        'exe': alias,
+        'probe-prefix': 'qemu.system.' + tname,
+      }]
+    endforeach
+  endforeach
+endif
+
 # Other build targets
 
 if get_option('plugins')
-- 
2.52.0.windows.1



^ permalink raw reply related	[flat|nested] 57+ messages in thread

* Re: [PATCH 06/12] hw/loongarch/virt: prefix ACPI helper with loongarch_virt_
  2026-08-23 15:07 ` [PATCH 06/12] hw/loongarch/virt: prefix ACPI helper with loongarch_virt_ Yonggang Luo
@ 2026-08-24  1:00   ` gaosong
  2026-08-24  7:20   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 57+ messages in thread
From: gaosong @ 2026-08-24  1:00 UTC (permalink / raw)
  To: Yonggang Luo, qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

在 2026/8/23 下午11:07, Yonggang Luo 写道:
> - virt_acpi_setup is the same C symbol used by ARM and RISC-V virt.
>    Rename it now so a later combined binary does not need meson -D
>    prefixes for LoongArch.
> - Rename the file-local virt_is_acpi_enabled to
>    loongarch_virt_is_acpi_enabled to match.
>
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>   hw/loongarch/virt-acpi-build.c | 6 +++---
>   hw/loongarch/virt.c            | 2 +-
>   include/hw/loongarch/virt.h    | 2 +-
>   3 files changed, 5 insertions(+), 5 deletions(-)
Reviewed-by: Song Gao <gaosong@loongson.cn>

Thanks.
Song Gao
> diff --git a/hw/loongarch/virt-acpi-build.c b/hw/loongarch/virt-acpi-build.c
> index a0b445f297b..bbbac289b49 100644
> --- a/hw/loongarch/virt-acpi-build.c
> +++ b/hw/loongarch/virt-acpi-build.c
> @@ -674,7 +674,7 @@ static const VMStateDescription vmstate_acpi_build = {
>       },
>   };
>   
> -static bool virt_is_acpi_enabled(LoongArchVirtMachineState *lvms)
> +static bool loongarch_virt_is_acpi_enabled(LoongArchVirtMachineState *lvms)
>   {
>       if (lvms->acpi == ON_OFF_AUTO_OFF) {
>           return false;
> @@ -682,7 +682,7 @@ static bool virt_is_acpi_enabled(LoongArchVirtMachineState *lvms)
>       return true;
>   }
>   
> -void virt_acpi_setup(LoongArchVirtMachineState *lvms)
> +void loongarch_virt_acpi_setup(LoongArchVirtMachineState *lvms)
>   {
>       AcpiBuildTables tables;
>       AcpiBuildState *build_state;
> @@ -692,7 +692,7 @@ void virt_acpi_setup(LoongArchVirtMachineState *lvms)
>           return;
>       }
>   
> -    if (!virt_is_acpi_enabled(lvms)) {
> +    if (!loongarch_virt_is_acpi_enabled(lvms)) {
>           ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n");
>           return;
>       }
> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
> index 6693dea647b..74c9668b6e6 100644
> --- a/hw/loongarch/virt.c
> +++ b/hw/loongarch/virt.c
> @@ -242,7 +242,7 @@ static void virt_done(Notifier *notifier, void *data)
>       LoongArchVirtMachineState *lvms = container_of(notifier,
>                                         LoongArchVirtMachineState, machine_done);
>       virt_build_smbios(lvms);
> -    virt_acpi_setup(lvms);
> +    loongarch_virt_acpi_setup(lvms);
>       virt_fdt_setup(lvms);
>   }
>   
> diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
> index d39a9bbf5dd..72268466def 100644
> --- a/include/hw/loongarch/virt.h
> +++ b/include/hw/loongarch/virt.h
> @@ -132,7 +132,7 @@ struct LoongArchVirtMachineState {
>   
>   #define TYPE_LOONGARCH_VIRT_MACHINE  MACHINE_TYPE_NAME("virt")
>   OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState, LOONGARCH_VIRT_MACHINE)
> -void virt_acpi_setup(LoongArchVirtMachineState *lvms);
> +void loongarch_virt_acpi_setup(LoongArchVirtMachineState *lvms);
>   void virt_fdt_setup(LoongArchVirtMachineState *lvms);
>   
>   static inline bool virt_has_dmsi(LoongArchVirtMachineState *lvms)



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 04/12] hw/arm/virt: prefix ACPI helpers with arm_virt_
  2026-08-23 15:07 ` [PATCH 04/12] hw/arm/virt: prefix ACPI helpers with arm_virt_ Yonggang Luo
@ 2026-08-24  7:18   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 57+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-24  7:18 UTC (permalink / raw)
  To: Yonggang Luo, qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 23/8/26 17:07, Yonggang Luo wrote:
> - virt_acpi_setup and virt_is_acpi_enabled are generic names also used
>    by RISC-V and LoongArch virt. A combined binary cannot export two
>    functions with the same C symbol.
> - Rename the ARM helpers to arm_virt_acpi_setup and
>    arm_virt_is_acpi_enabled. Leave the trace event virt_acpi_setup
>    unchanged; it is a separate identifier.
> 
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>   hw/arm/virt-acpi-build.c |  4 ++--
>   hw/arm/virt.c            | 12 ++++++------
>   include/hw/arm/virt.h    |  4 ++--
>   3 files changed, 10 insertions(+), 10 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 05/12] hw/riscv/virt: prefix ACPI helpers with riscv_virt_
  2026-08-23 15:07 ` [PATCH 05/12] hw/riscv/virt: prefix ACPI helpers with riscv_virt_ Yonggang Luo
@ 2026-08-24  7:19   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 57+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-24  7:19 UTC (permalink / raw)
  To: Yonggang Luo, qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 23/8/26 17:07, Yonggang Luo wrote:
> - virt_acpi_setup and virt_is_acpi_enabled collide with ARM virt when
>    both architectures are linked into one qemu-system binary.
> - Rename the RISC-V helpers to riscv_virt_acpi_setup and
>    riscv_virt_is_acpi_enabled. Leave file-local virt_acpi_build* names
>    unchanged.
> 
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>   hw/riscv/virt-acpi-build.c | 2 +-
>   hw/riscv/virt.c            | 6 +++---
>   include/hw/riscv/virt.h    | 4 ++--
>   3 files changed, 6 insertions(+), 6 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 06/12] hw/loongarch/virt: prefix ACPI helper with loongarch_virt_
  2026-08-23 15:07 ` [PATCH 06/12] hw/loongarch/virt: prefix ACPI helper with loongarch_virt_ Yonggang Luo
  2026-08-24  1:00   ` gaosong
@ 2026-08-24  7:20   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 57+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-24  7:20 UTC (permalink / raw)
  To: Yonggang Luo, qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 23/8/26 17:07, Yonggang Luo wrote:
> - virt_acpi_setup is the same C symbol used by ARM and RISC-V virt.
>    Rename it now so a later combined binary does not need meson -D
>    prefixes for LoongArch.
> - Rename the file-local virt_is_acpi_enabled to
>    loongarch_virt_is_acpi_enabled to match.
> 
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>   hw/loongarch/virt-acpi-build.c | 6 +++---
>   hw/loongarch/virt.c            | 2 +-
>   include/hw/loongarch/virt.h    | 2 +-
>   3 files changed, 5 insertions(+), 5 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 07/12] target/riscv: uniquify TCG crc32, crc32c, and wfi helper names
  2026-08-23 15:07 ` [PATCH 07/12] target/riscv: uniquify TCG crc32, crc32c, and wfi helper names Yonggang Luo
@ 2026-08-24  7:22   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 57+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-24  7:22 UTC (permalink / raw)
  To: Yonggang Luo, qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 23/8/26 17:07, Yonggang Luo wrote:
> - ARM already exports helper_crc32, helper_crc32c, helper_wfi, and the
>    matching helper_info_* objects. RISC-V used the same DEF_HELPER names,
>    which collide in a combined qemu-system link.
> - Rename the RISC-V helpers to riscv_crc32, riscv_crc32c, and riscv_wfi
>    so the generated C symbols are unique without meson -D prefixes.
> 
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>   target/riscv/helper.h                              | 6 +++---
>   target/riscv/tcg/bitmanip_helper.c                 | 4 ++--
>   target/riscv/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 +-
>   5 files changed, 9 insertions(+), 9 deletions(-)

https://lore.kernel.org/qemu-devel/20260623110209.26861-1-philmd@oss.qualcomm.com/
;)


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 12/12] meson: link ARM and RISC-V into qemu-system
  2026-08-23 15:07 ` [PATCH 12/12] meson: link ARM and RISC-V into qemu-system Yonggang Luo
@ 2026-08-24 16:20   ` Pierrick Bouvier
  2026-08-24 19:04     ` Yonggang Luo
  2026-08-26 13:00     ` Daniel P. Berrangé
  0 siblings, 2 replies; 57+ messages in thread
From: Pierrick Bouvier @ 2026-08-24 16:20 UTC (permalink / raw)
  To: Yonggang Luo, qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

[-- Attachment #1: Type: text/plain, Size: 8314 bytes --]

On 8/23/2026 8:07 AM, Yonggang Luo wrote:
> - Build qemu-system (and qemu-systemw on Windows) from aarch64
>   common/system objects plus RISC-V arch objects taken from the
>   existing riscv64 lib.
> - Pull 32-bit TargetInfo and 32-only boards from the arm/riscv32
>   libs so hw/arm and target/riscv are not compiled twice.
> - Skip linking qemu-system-{arm,aarch64,riscv32,riscv64} and the
>   Windows *w variants; symlink those names to qemu-system so
>   argv[0] still selects TargetInfo.
> 
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>  meson.build | 156 +++++++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 147 insertions(+), 9 deletions(-)
> 
> diff --git a/meson.build b/meson.build
> index 449d50f2983..b4f435f6a22 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -4250,6 +4250,10 @@ endif
>  
>  traceable = []
>  emulators = {}
> +target_softmmu = {}
> +combo_softmmu = ['aarch64-softmmu', 'arm-softmmu', 'riscv32-softmmu', 'riscv64-softmmu']
> +have_qemu_system_combo = ('aarch64-softmmu' in target_dirs
> +                          and 'riscv64-softmmu' in target_dirs)
>  foreach target : target_dirs
>    config_target = config_target_mak[target]
>    target_name = config_target['TARGET_NAME']
> @@ -4399,20 +4403,37 @@ foreach target : target_dirs
>                   c_args: c_args,
>                   build_by_default: false)
>  
> +  if target in combo_softmmu
> +    target_softmmu += {target: {
> +      'lib': lib,
> +      'arch_srcs': arch_srcs,
> +      'arch_deps': arch_deps,
> +      'c_args': c_args,
> +      'link_args': link_args,
> +      'target_stubs': target_stubs,
> +      'main_rs': main_rs,
> +      'config_target': config_target,
> +      'target_base_arch': target_base_arch,
> +    }}
> +  endif
> +
>    if target.endswith('-softmmu')
> -    execs = [{
> -      'name': 'qemu-system-' + target_name,
> -      'win_subsystem': 'console',
> -      'sources': [main_rs, files('system/main.c')],
> -      'dependencies': [sdl, target_stubs],
> -    }]
> -    if host_os == 'windows' and (sdl.found() or gtk.found())
> +    execs = []
> +    if not (have_qemu_system_combo and target in combo_softmmu)
>        execs += [{
> -        'name': 'qemu-system-' + target_name + 'w',
> -        'win_subsystem': 'windows',
> +        'name': 'qemu-system-' + target_name,
> +        'win_subsystem': 'console',
>          'sources': [main_rs, files('system/main.c')],
>          'dependencies': [sdl, target_stubs],
>        }]
> +      if host_os == 'windows' and (sdl.found() or gtk.found())
> +        execs += [{
> +          'name': 'qemu-system-' + target_name + 'w',
> +          'win_subsystem': 'windows',
> +          'sources': [main_rs, files('system/main.c')],
> +          'dependencies': [sdl, target_stubs],
> +        }]
> +      endif
>      endif
>      if get_option('fuzzing')
>        specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
> @@ -4481,6 +4502,123 @@ foreach target : target_dirs
>    endforeach
>  endforeach
>  
> +# Combined ARM + RISC-V system emulator (32 and 64).
> +# Common/system objects come from aarch64. RISC-V arch objects come
> +# from the existing riscv64 lib. 32-bit TargetInfo and 32-only boards
> +# come from the arm/riscv32 libs. Per-target qemu-system-* names are
> +# symlinks to qemu-system (argv[0] selects TargetInfo).
> +if have_qemu_system_combo
> +  a64 = target_softmmu['aarch64-softmmu']
> +  rv = target_softmmu['riscv64-softmmu']
> +  extra_objs = []
> +  target_info_def = files('target-info-def.c')
> +  foreach spec : [[common_ss, common_all], [system_ss, libsystem]]
> +    rv_src = spec[0].apply(rv['config_target'], strict: false)
> +    a64_src = spec[0].apply(a64['config_target'], strict: false)
> +    extra = []
> +    foreach f : rv_src.sources()
> +      if f not in a64_src.sources() and not f.full_path().endswith('_stubs.c')
> +        extra += f
> +      endif
> +    endforeach
> +    if extra.length() > 0
> +      extra_objs += spec[1].extract_objects(extra)
> +    endif
> +  endforeach
> +  rv_base = rv['target_base_arch']
> +  if rv_base in target_common_arch_libs
> +    src = target_common_arch[rv_base].apply(rv['config_target'], strict: false)
> +    extra_objs += target_common_arch_libs[rv_base].extract_objects(src.sources())
> +  endif
> +  if rv_base in target_common_system_arch_libs
> +    src = target_common_system_arch[rv_base].apply(rv['config_target'], strict: false)
> +    extra_objs += target_common_system_arch_libs[rv_base].extract_objects(src.sources())
> +  endif
> +  foreach pair : [['arm-softmmu', 'aarch64-softmmu'], ['riscv32-softmmu', 'riscv64-softmmu']]
> +    t32 = pair[0]
> +    t64 = pair[1]
> +    if t32 in target_softmmu
> +      extra_objs += target_softmmu[t32]['lib'].extract_objects(target_info_def)
> +      base32 = target_softmmu[t32]['target_base_arch']
> +      if base32 in hw_arch
> +        hw32 = hw_arch[base32].apply(target_softmmu[t32]['config_target'], strict: false)
> +        hw64 = hw_arch[base32].apply(target_softmmu[t64]['config_target'], strict: false)
> +        extra_hw = []
> +        foreach f : hw32.sources()
> +          if f not in hw64.sources()
> +            extra_hw += f
> +          endif
> +        endforeach
> +        if extra_hw.length() > 0
> +          extra_objs += target_softmmu[t32]['lib'].extract_objects(extra_hw)
> +        endif
> +      endif
> +    endif
> +  endforeach
> +  combo_objects = extra_objs
> +  combo_objects += a64['lib'].extract_all_objects(recursive: true)
> +  combo_objects += rv['lib'].extract_objects(rv['arch_srcs'])
> +  combo_deps = a64['arch_deps'] + rv['arch_deps'] + [sdl, a64['target_stubs'], rv['target_stubs']]
> +  if 'arm-softmmu' in target_softmmu
> +    combo_deps += target_softmmu['arm-softmmu']['arch_deps']
> +  endif
> +  if 'riscv32-softmmu' in target_softmmu
> +    combo_deps += target_softmmu['riscv32-softmmu']['arch_deps']
> +  endif
> +  combo_execs = [{
> +    'name': 'qemu-system',
> +    'win_subsystem': 'console',
> +  }]
> +  if host_os == 'windows' and (sdl.found() or gtk.found())
> +    combo_execs += [{
> +      'name': 'qemu-systemw',
> +      'win_subsystem': 'windows',
> +    }]
> +  endif
> +  combo_exe_suffix = host_os == 'windows' ? '.exe' : ''
> +  combo_alias_py = 'import os, sys; src, dst = sys.argv[1:3]; os.path.exists(dst) and os.remove(dst); os.symlink(os.path.basename(src), dst)'
> +  foreach exe : combo_execs
> +    emulator = executable(exe['name'], [a64['main_rs'], files('system/main.c')],
> +               install: true,
> +               c_args: a64['c_args'],
> +               dependencies: combo_deps,
> +               objects: combo_objects,
> +               link_depends: [block_syms, qemu_syms],
> +               link_args: a64['link_args'],
> +               win_subsystem: exe['win_subsystem'])
> +    emulators += {exe['name']: emulator}
> +    traceable += [{
> +      'exe': exe['name'],
> +      'probe-prefix': 'qemu.system.multi',
> +    }]
> +    foreach t : combo_softmmu
> +      if t not in target_softmmu
> +        continue
> +      endif
> +      tname = target_softmmu[t]['config_target']['TARGET_NAME']
> +      if exe['name'] == 'qemu-systemw'
> +        alias = 'qemu-system-' + tname + 'w'
> +      else
> +        alias = 'qemu-system-' + tname
> +      endif
> +      alias_tgt = custom_target(alias,
> +                                input: emulator,
> +                                output: alias + combo_exe_suffix,
> +                                command: [python, '-c', combo_alias_py, '@INPUT@', '@OUTPUT@'],
> +                                build_by_default: true,
> +                                install: false)
> +      emulators += {alias: alias_tgt}
> +      install_symlink(alias + combo_exe_suffix,
> +                      pointing_to: exe['name'] + combo_exe_suffix,
> +                      install_dir: get_option('bindir'))
> +      traceable += [{
> +        'exe': alias,
> +        'probe-prefix': 'qemu.system.' + tname,
> +      }]
> +    endforeach
> +  endforeach
> +endif
> +
>  # Other build targets
>  
>  if get_option('plugins')

Please find attached a much simpler implementation, which only requires
a single line update as we add new targets in single-binary.

Regards,
Pierrick

[-- Attachment #2: 6261b0c255e1a8f0df2b41928b8dfb365d0fa488.patch.txt --]
[-- Type: text/plain, Size: 3013 bytes --]

From 6261b0c255e1a8f0df2b41928b8dfb365d0fa488 Mon Sep 17 00:00:00 2001
From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Date: Tue, 14 Apr 2026 10:56:15 -0700
Subject: [PATCH] meson: build single binary

This is not built by default.
Build with: ninja -C build qemu-system

All available *-softmmu targets are aggregated, ./configure
--target-list can be used to restrict which targets are included.

In case user has targets that are not supported, we emit an error
message when build qemu-system target. This way, it's not necessary to
have a custom configure flag, and qemu-system can live next to existing
binaries without complexifying the workflow more than it is already.

Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
---
 meson.build | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/meson.build b/meson.build
index 553df3e7f053..4a31a520d9eb 100644
--- a/meson.build
+++ b/meson.build
@@ -4264,6 +4264,9 @@ if host_os == 'darwin'
 endif
 
 traceable = []
+single_binary_libs = []
+single_binary_deps = []
+single_binary_crates = []
 emulators = {}
 foreach target : target_dirs
   config_target = config_target_mak[target]
@@ -4419,6 +4422,10 @@ foreach target : target_dirs
                  build_by_default: false)
 
   if target.endswith('-softmmu')
+    single_binary_libs += lib
+    single_binary_deps += arch_deps
+    single_binary_deps += target_stubs
+    single_binary_crates += main_rs
     execs = [{
       'name': 'qemu-system-' + target_name,
       'win_subsystem': 'console',
@@ -4500,6 +4507,47 @@ foreach target : target_dirs
   endforeach
 endforeach
 
+single_binary_objects = []
+foreach lib: single_binary_libs
+  single_binary_objects += lib.extract_all_objects(recursive: true)
+endforeach
+
+single_binary_link_args = emulator_link_args
+single_binary_link_args += enable_modules ? ['@block.syms', '@qemu.syms'] : []
+
+supported_targets = [
+  'aarch64-softmmu',
+  'arm-softmmu',
+]
+unsupported_targets = []
+foreach target : target_dirs
+  if target.endswith('-softmmu') and target not in supported_targets
+    unsupported_targets += target
+  endif
+endforeach
+
+if unsupported_targets.length() == 0
+  executable('qemu-system',
+             sources: [single_binary_crates, files('system/main.c')],
+             dependencies: single_binary_deps,
+             objects: single_binary_objects,
+             link_depends: [block_syms, qemu_syms],
+             link_args: single_binary_link_args,
+             build_by_default: false)
+else
+  error_str = f'''qemu-system only support targets:
+@supported_targets@
+
+unsupported targets:
+@unsupported_targets@
+
+use ./configure --target-list= to choose list of targets'''
+  t = custom_target(command: ['sh', '-c', 'echo "' + error_str + '" && exit 1'],
+                    output: 'none',
+                    build_by_default: false)
+  alias_target('qemu-system', t)
+endif
+
 # Other build targets
 
 if get_option('plugins')

^ permalink raw reply related	[flat|nested] 57+ messages in thread

* Re: [PATCH 09/12] target-info: register le and be TargetInfo variants
  2026-08-23 15:07 ` [PATCH 09/12] target-info: register le and be TargetInfo variants Yonggang Luo
@ 2026-08-24 16:22   ` Pierrick Bouvier
  2026-08-24 19:01     ` Yonggang Luo
  0 siblings, 1 reply; 57+ messages in thread
From: Pierrick Bouvier @ 2026-08-24 16:22 UTC (permalink / raw)
  To: Yonggang Luo, qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 8/23/2026 8:07 AM, Yonggang Luo wrote:
> - Register target-info-<name>-le and -be from one system
>   target-info-def.c unit, sharing arch fields.
> - Mark is_default from TARGET_BIG_ENDIAN so riscv/arm stay LE and
>   ppc/s390x stay BE when -target is omitted.
> - Pick the unique default in target_info_qom_set_target() when more
>   than one TargetInfo is registered. Leave user-mode as a single
>   target_info().
> 
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>  include/qemu/target-info-impl.h |  6 ++++
>  include/qemu/target-info-init.h | 29 +++++++++++++---
>  target-info-def.c               | 61 +++++++++++++++++++++++++--------
>  target-info-qom.c               | 33 ++++++++++++++----
>  4 files changed, 104 insertions(+), 25 deletions(-)
> 
> diff --git a/include/qemu/target-info-impl.h b/include/qemu/target-info-impl.h
> index de329ec2b86..b4222e4455e 100644
> --- a/include/qemu/target-info-impl.h
> +++ b/include/qemu/target-info-impl.h
> @@ -23,6 +23,12 @@ typedef struct TargetInfo {
>      const char *cpu_type;
>      /* related to TARGET_BIG_ENDIAN definition */
>      EndianMode endianness;
> +    /*
> +     * True on the endian variant that matches this translation unit's
> +     * TARGET_BIG_ENDIAN. target_info_qom_set_target() uses this when
> +     * more than one TargetInfo is registered and -target is omitted.
> +     */
> +    bool is_default;
>      /*
>       * runtime equivalent of
>       *   TARGET_PAGE_BITS_VARY ? TARGET_PAGE_BITS_LEGACY : TARGET_PAGE_BITS
> diff --git a/include/qemu/target-info-init.h b/include/qemu/target-info-init.h
> index b7024c9faef..25d00adcc66 100644
> --- a/include/qemu/target-info-init.h
> +++ b/include/qemu/target-info-init.h
> @@ -37,15 +37,34 @@ const TargetInfo *target_info(void)     \
>  #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,                                \
> +/*
> + * QOM type names are target-info-<TARGET_NAME>-le and -be so both
> + * endian variants can be registered from one system translation unit.
> + */
> +#define TARGET_INFO_QOM_SUFFIX_0 "-le"
> +#define TARGET_INFO_QOM_SUFFIX_1 "-be"
> +
> +#define TARGET_INFO_QOM_NAME(sel)                                           \
> +    TYPE_TARGET_INFO "-" TARGET_NAME glue(TARGET_INFO_QOM_SUFFIX_, sel)
> +
> +#define TARGET_INFO_QOM_TYPEINFO(ti_var, sel)                               \
> +static const TypeInfo glue(target_info_qom_type_, sel) = {                  \
> +    .name = TARGET_INFO_QOM_NAME(sel),                                      \
>      .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)
> +}
> +
> +#define target_info_init_le_be(ti_le, ti_be)                                \
> +TARGET_INFO_QOM_TYPEINFO(ti_le, 0);                                         \
> +TARGET_INFO_QOM_TYPEINFO(ti_be, 1);                                         \
> +static void do_qemu_init_target_info(void)                                  \
> +{                                                                           \
> +    type_register_static(&target_info_qom_type_0);                          \
> +    type_register_static(&target_info_qom_type_1);                          \
> +}                                                                           \
> +module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO)
>  
>  #endif /* CONFIG_USER_ONLY */
>  #endif /* COMPILING_PER_TARGET */
> diff --git a/target-info-def.c b/target-info-def.c
> index 5d38e405735..6722c43a08f 100644
> --- a/target-info-def.c
> +++ b/target-info-def.c
> @@ -28,39 +28,72 @@ QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) != sizeof(CPUState));
>  QEMU_BUILD_BUG_ON(TARGET_PAGE_BITS < TARGET_PAGE_BITS_MIN);
>  #endif
>  
> -static const TargetInfo target_info_def = {
> -    .target_name = TARGET_NAME,
> -    .target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH),
> -    .long_bits = TARGET_LONG_BITS,
> -    .cpu_type = CPU_RESOLVING_TYPE,
> -    .endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG : ENDIAN_MODE_LITTLE,
>  #ifdef TARGET_PAGE_BITS_VARY
> -    .page_bits_vary = true,
>  # ifdef TARGET_PAGE_BITS_LEGACY
> +#  define TARGET_INFO_PAGE_BITS \
> +    .page_bits_vary = true, \
>      .page_bits_init = TARGET_PAGE_BITS_LEGACY,
> +# else
> +#  define TARGET_INFO_PAGE_BITS \
> +    .page_bits_vary = true,
>  # endif
>  #else
> -    .page_bits_vary = false,
> +# define TARGET_INFO_PAGE_BITS \
> +    .page_bits_vary = false, \
>      .page_bits_init = TARGET_PAGE_BITS,
>  #endif
>  
>  #ifndef CONFIG_USER_ONLY
>  # ifdef CONFIG_MULTIPROCESS
> -    .config_multiprocess = true,
> +#  define TARGET_INFO_CONFIG_MULTIPROCESS .config_multiprocess = true,
>  # else
> -    .config_multiprocess = false,
> +#  define TARGET_INFO_CONFIG_MULTIPROCESS .config_multiprocess = false,
>  # endif
>  # ifdef CONFIG_NITRO
> -    .config_nitro = true,
> +#  define TARGET_INFO_CONFIG_NITRO .config_nitro = true,
>  # else
> -    .config_nitro = false,
> +#  define TARGET_INFO_CONFIG_NITRO .config_nitro = false,
>  # endif
>  # ifdef CONFIG_XEN
> -    .config_xen = true,
> +#  define TARGET_INFO_CONFIG_XEN .config_xen = true,
>  # else
> -    .config_xen = false,
> +#  define TARGET_INFO_CONFIG_XEN .config_xen = false,
>  # endif
> +# define TARGET_INFO_CONFIG \
> +    TARGET_INFO_CONFIG_MULTIPROCESS \
> +    TARGET_INFO_CONFIG_NITRO \
> +    TARGET_INFO_CONFIG_XEN
> +#else
> +# define TARGET_INFO_CONFIG
>  #endif
> +
> +#define TARGET_INFO_COMMON                                                  \
> +    .target_name = TARGET_NAME,                                             \
> +    .target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH),                      \
> +    .long_bits = TARGET_LONG_BITS,                                          \
> +    .cpu_type = CPU_RESOLVING_TYPE,                                         \
> +    TARGET_INFO_PAGE_BITS                                                   \
> +    TARGET_INFO_CONFIG
> +
> +#ifdef CONFIG_USER_ONLY
> +static const TargetInfo target_info_def = {
> +    TARGET_INFO_COMMON
> +    .endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG : ENDIAN_MODE_LITTLE,
>  };
>  
>  target_info_init(target_info_def)
> +#else
> +static const TargetInfo target_info_le = {
> +    TARGET_INFO_COMMON
> +    .endianness = ENDIAN_MODE_LITTLE,
> +    .is_default = !TARGET_BIG_ENDIAN,
> +};
> +
> +static const TargetInfo target_info_be = {
> +    TARGET_INFO_COMMON
> +    .endianness = ENDIAN_MODE_BIG,
> +    .is_default = TARGET_BIG_ENDIAN,
> +};
> +
> +target_info_init_le_be(target_info_le, target_info_be)
> +#endif
> diff --git a/target-info-qom.c b/target-info-qom.c
> index 68ad734049c..2c1c57b05fd 100644
> --- a/target-info-qom.c
> +++ b/target-info-qom.c
> @@ -90,13 +90,34 @@ const TargetInfo *target_info(void)
>  void target_info_qom_set_target(void)
>  {
>      g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
> -
> +    const TargetInfo *chosen = NULL;
>      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");
> +    size_t num_default = 0;
> +
> +    if (num_found == 0) {
> +        error_setg(&error_fatal, "no target-info is available");
> +    }
> +
> +    if (num_found == 1) {
> +        target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info;
> +        return;
> +    }
> +
> +    for (GSList *l = targets; l; l = l->next) {
> +        const TargetInfo *ti = TARGET_INFO_CLASS(l->data)->target_info;
> +
> +        if (ti->is_default) {
> +            num_default++;
> +            chosen = ti;
> +        }
> +    }
> +
> +    if (num_default != 1) {
> +        error_setg(&error_fatal, num_default == 0 ?
> +                                 "no default target-info is available" :
> +                                 "more than one default target-info "
> +                                 "is available");
>      }
>  
> -    target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info;
> +    target_info_ptr = chosen;
>  }

Is it representing existing targets, or adding new ones per endianness?
I'm not sure if the goal is to add new binaries, or mimic existing ones
with specific parameters.


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 10/12] target-info: add -target and program-name selection
  2026-08-23 15:07 ` [PATCH 10/12] target-info: add -target and program-name selection Yonggang Luo
@ 2026-08-24 16:24   ` Pierrick Bouvier
  2026-08-26 12:46   ` Daniel P. Berrangé
  1 sibling, 0 replies; 57+ messages in thread
From: Pierrick Bouvier @ 2026-08-24 16:24 UTC (permalink / raw)
  To: Yonggang Luo, qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

[-- Attachment #1: Type: text/plain, Size: 12159 bytes --]

On 8/23/2026 8:07 AM, Yonggang Luo wrote:
> - Parse -target before TargetInfo is fixed; CLI overrides the program
>   basename.
> - Tokens are target_name or target_name-be / -le; -target help lists
>   registered names in sorted order.
> - When -target is omitted, infer the token from g_get_prgname(): strip
>   .exe, take the longest dash-separated registered suffix, and retry
>   without a trailing w for Windows GUI binaries.
> - A basename that matches no registered token falls through to the
>   unique default. Combined binaries with no suffix require -target
>   when more than one default TargetInfo is registered.
> 
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>  include/qemu/target-info-qom.h |  10 +-
>  qemu-options.hx                |  13 +++
>  system/vl.c                    |  28 ++++--
>  target-info-qom.c              | 167 ++++++++++++++++++++++++++++++---
>  tests/qtest/fuzz/fuzz.c        |   2 +-
>  5 files changed, 197 insertions(+), 23 deletions(-)
> 
> diff --git a/include/qemu/target-info-qom.h b/include/qemu/target-info-qom.h
> index 842cf241e0a..3b59cf82d65 100644
> --- a/include/qemu/target-info-qom.h
> +++ b/include/qemu/target-info-qom.h
> @@ -40,7 +40,15 @@ typedef struct TargetInfoQomClass {
>  
>  OBJECT_DECLARE_TYPE(TargetInfoQom, TargetInfoQomClass, TARGET_INFO)
>  
> -void target_info_qom_set_target(void);
> +/**
> + * target_info_qom_set_target:
> + * @name: -target token, or NULL/%empty to infer from the program
> + * basename or the unique default
> + *
> + * Tokens are target_name (arch default endian) or target_name-be /
> + * target_name-le. -target overrides the program basename.
> + */
> +void target_info_qom_set_target(const char *name);
>  
>  /**
>   * get_machine_types_available:
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 34970fffc94..638b531aa49 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -223,6 +223,19 @@ SRST
>      as -machine.
>  ERST
>  
> +DEF("target", HAS_ARG, QEMU_OPTION_target,
> +    "-target name    select target ('-target help' for list)\n", QEMU_ARCH_ALL)
> +SRST
> +``-target name``
> +    Select the emulation target (``-target help`` for the list). The
> +    default endian is the architecture default (``riscv64`` is little
> +    endian). The other endian uses a ``-be`` or ``-le`` suffix
> +    (``riscv64-be``, ``ppc64-le``). If omitted, a matching suffix of
> +    the program basename is used (``qemu-system-riscv64-be``, and
> +    ``qemu-system-aarch64w.exe`` on Windows). ``-target`` overrides
> +    the program name.
> +ERST
> +
>  DEF("cpu", HAS_ARG, QEMU_OPTION_cpu,
>      "-cpu cpu        select CPU ('-cpu help' for list)\n", QEMU_ARCH_ALL)
>  SRST
> diff --git a/system/vl.c b/system/vl.c
> index 83b9425de9b..405f434e036 100644
> --- a/system/vl.c
> +++ b/system/vl.c
> @@ -166,6 +166,7 @@ typedef struct DeviceOption {
>      QTAILQ_ENTRY(DeviceOption) next;
>  } DeviceOption;
>  
> +static const char *target_option;
>  static const char *cpu_option;
>  static const char *mem_path;
>  static const char *incoming;
> @@ -2899,19 +2900,12 @@ 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());
> -
> -    qemu_init_subsystems();
> -
> -    /* first pass of option parsing */
> +    /*
> +     * First pass: options needed before TargetInfo is fixed.
> +     */
>      optind = 1;
>      while (optind < argc) {
>          if (argv[optind][0] != '-') {
> -            /* disk image */
>              optind++;
>          } else {
>              const QEMUOption *popt;
> @@ -2921,10 +2915,21 @@ void qemu_init(int argc, char **argv)
>              case QEMU_OPTION_nouserconfig:
>                  userconfig = false;
>                  break;
> +            case QEMU_OPTION_target:
> +                target_option = optarg;
> +                break;
>              }
>          }
>      }
>  
> +    module_call_init(MODULE_INIT_TARGET_INFO);
> +    target_info_qom_set_target(target_option);
> +
> +    module_init_info(qemu_modinfo);
> +    module_allow_arch(target_name());
> +
> +    qemu_init_subsystems();
> +
>      machine_opts_dict = qdict_new();
>      if (userconfig) {
>          qemu_read_default_config_file(&error_fatal);
> @@ -3687,6 +3692,9 @@ void qemu_init(int argc, char **argv)
>              case QEMU_OPTION_nouserconfig:
>                  /* Nothing to be parsed here. Especially, do not error out below. */
>                  break;
> +            case QEMU_OPTION_target:
> +                /* Parsed before TargetInfo is selected. */
> +                break;
>  #if defined(CONFIG_POSIX) && !defined(EMSCRIPTEN)
>              case QEMU_OPTION_daemonize:
>                  os_set_daemonize(true);
> diff --git a/target-info-qom.c b/target-info-qom.c
> index 2c1c57b05fd..be03573a699 100644
> --- a/target-info-qom.c
> +++ b/target-info-qom.c
> @@ -7,6 +7,7 @@
>   */
>  
>  #include "qemu/osdep.h"
> +#include "qemu/help_option.h"
>  #include "qapi/error.h"
>  #include "qom/object.h"
>  #include "qemu/target-info-impl.h"
> @@ -87,7 +88,139 @@ const TargetInfo *target_info(void)
>      return target_info_ptr;
>  }
>  
> -void target_info_qom_set_target(void)
> +static const TargetInfo *target_info_from_class(ObjectClass *oc)
> +{
> +    return TARGET_INFO_CLASS(oc)->target_info;
> +}
> +
> +/* Default token is target_name; the other endian is target_name-le or -be. */
> +static char *target_info_option_name(const TargetInfo *ti)
> +{
> +    if (ti->is_default) {
> +        return g_strdup(ti->target_name);
> +    }
> +    if (ti->endianness == ENDIAN_MODE_BIG) {
> +        return g_strdup_printf("%s-be", ti->target_name);
> +    }
> +    return g_strdup_printf("%s-le", ti->target_name);
> +}
> +
> +static gint target_info_token_name_cmp(gconstpointer a, gconstpointer b,
> +                                       gpointer data)
> +{
> +    const TargetInfo *ta = target_info_from_class((ObjectClass *)a);
> +    const TargetInfo *tb = target_info_from_class((ObjectClass *)b);
> +    g_autofree char *na = target_info_option_name(ta);
> +    g_autofree char *nb = target_info_option_name(tb);
> +
> +    return strcmp(na, nb);
> +}
> +
> +static void G_NORETURN target_info_list_and_exit(GSList *targets)
> +{
> +    printf("Supported targets:\n");
> +    for (GSList *l = targets; l; l = l->next) {
> +        const TargetInfo *ti = target_info_from_class(l->data);
> +        g_autofree char *opt_name = target_info_option_name(ti);
> +
> +        printf("  %s%s\n", opt_name, ti->is_default ? " (default)" : "");
> +    }
> +    exit(0);
> +}
> +
> +static const TargetInfo *target_info_find_default(GSList *targets,
> +                                                  size_t *num_default)
> +{
> +    const TargetInfo *chosen = NULL;
> +
> +    *num_default = 0;
> +    for (GSList *l = targets; l; l = l->next) {
> +        const TargetInfo *ti = target_info_from_class(l->data);
> +
> +        if (ti->is_default) {
> +            (*num_default)++;
> +            chosen = ti;
> +        }
> +    }
> +    return chosen;
> +}
> +
> +static const TargetInfo *target_info_find_token(GSList *targets,
> +                                                const char *token)
> +{
> +    for (GSList *l = targets; l; l = l->next) {
> +        const TargetInfo *ti = target_info_from_class(l->data);
> +        g_autofree char *opt_name = target_info_option_name(ti);
> +
> +        if (!strcmp(opt_name, token)) {
> +            return ti;
> +        }
> +    }
> +    return NULL;
> +}
> +
> +static bool target_info_base_match_token(const char *base, const char *token)
> +{
> +    size_t nlen = strlen(token);
> +    size_t blen;
> +
> +    if (!base || !token[0] || !g_str_has_suffix(base, token)) {
> +        return false;
> +    }
> +    blen = strlen(base);
> +    return blen == nlen || base[blen - nlen - 1] == '-';
> +}
> +
> +static const TargetInfo *target_info_find_prgname(GSList *targets,
> +                                                  const char *base)
> +{
> +    const TargetInfo *chosen = NULL;
> +    size_t best_len = 0;
> +
> +    if (!base || !base[0]) {
> +        return NULL;
> +    }
> +
> +    for (GSList *l = targets; l; l = l->next) {
> +        const TargetInfo *ti = target_info_from_class(l->data);
> +        g_autofree char *opt_name = target_info_option_name(ti);
> +        size_t nlen = strlen(opt_name);
> +
> +        if (nlen > best_len &&
> +            target_info_base_match_token(base, opt_name)) {
> +            chosen = ti;
> +            best_len = nlen;
> +        }
> +    }
> +    return chosen;
> +}
> +
> +static const TargetInfo *target_info_from_prgname(GSList *targets)
> +{
> +    const char *prg = g_get_prgname();
> +    g_autofree char *base = NULL;
> +    char *dot;
> +    const TargetInfo *chosen;
> +
> +    if (!prg || !prg[0]) {
> +        return NULL;
> +    }
> +
> +    base = g_path_get_basename(prg);
> +    dot = strrchr(base, '.');
> +    if (dot && g_ascii_strcasecmp(dot, ".exe") == 0) {
> +        *dot = '\0';
> +    }
> +
> +    chosen = target_info_find_prgname(targets, base);
> +    if (!chosen && strlen(base) > 1 && g_str_has_suffix(base, "w")) {
> +        base[strlen(base) - 1] = '\0';
> +        chosen = target_info_find_prgname(targets, base);
> +    }
> +    return chosen;
> +}
> +
> +void target_info_qom_set_target(const char *name)
>  {
>      g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
>      const TargetInfo *chosen = NULL;
> @@ -98,25 +231,37 @@ void target_info_qom_set_target(void)
>          error_setg(&error_fatal, "no target-info is available");
>      }
>  
> -    if (num_found == 1) {
> -        target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info;
> +    if (name && is_help_option(name)) {
> +        targets = g_slist_sort_with_data(targets, target_info_token_name_cmp,
> +                                         NULL);
> +        target_info_list_and_exit(targets);
> +    }
> +
> +    if (name && name[0]) {
> +        chosen = target_info_find_token(targets, name);
> +        if (!chosen) {
> +            error_setg(&error_fatal, "unknown target '%s'", name);
> +        }
> +        target_info_ptr = chosen;
>          return;
>      }
>  
> -    for (GSList *l = targets; l; l = l->next) {
> -        const TargetInfo *ti = TARGET_INFO_CLASS(l->data)->target_info;
> +    chosen = target_info_from_prgname(targets);
> +    if (chosen) {
> +        target_info_ptr = chosen;
> +        return;
> +    }
>  
> -        if (ti->is_default) {
> -            num_default++;
> -            chosen = ti;
> -        }
> +    if (num_found == 1) {
> +        target_info_ptr = target_info_from_class(targets->data);
> +        return;
>      }
>  
> +    chosen = target_info_find_default(targets, &num_default);
>      if (num_default != 1) {
>          error_setg(&error_fatal, num_default == 0 ?
>                                   "no default target-info is available" :
> -                                 "more than one default target-info "
> -                                 "is available");
> +                                 "multiple default targets; use -target");
>      }
>  
>      target_info_ptr = chosen;
> diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c
> index a3a131c80f8..489c7138bb9 100644
> --- a/tests/qtest/fuzz/fuzz.c
> +++ b/tests/qtest/fuzz/fuzz.c
> @@ -174,7 +174,7 @@ 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();
> +    target_info_qom_set_target(NULL);
>      module_call_init(MODULE_INIT_FUZZ_TARGET);
>      module_call_init(MODULE_INIT_QOM);
>      module_call_init(MODULE_INIT_LIBQOS);

It could at least be useful to list available targets for users when the
one passed is incorrect, or when they must pick one.

See patch attached for inspiration.

Regards,
Pierrick


[-- Attachment #2: a3e5a8f350e14ce533262b29e7dc37af6d76425d.patch.txt --]
[-- Type: text/plain, Size: 5606 bytes --]

From a3e5a8f350e14ce533262b29e7dc37af6d76425d Mon Sep 17 00:00:00 2001
From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Date: Sun, 17 May 2026 21:40:22 +0000
Subject: [PATCH] system/vl: add new option -target

This commit adds a new option -target, which can be allowed to set
current target, or retrieve list of targets available with 'help'.

This option is the first we need to handle, as all the rest of
initialization depends on it.

Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
---
 include/qemu/target-info-qom.h |  1 +
 qemu-options.hx                |  8 ++++++++
 system/vl.c                    | 34 +++++++++++++++++++++++++++++++++-
 target-info-qom.c              | 33 ++++++++++++++++++++++++++++++++-
 4 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/include/qemu/target-info-qom.h b/include/qemu/target-info-qom.h
index 91be415ed33f2..87f3a51ccd4af 100644
--- a/include/qemu/target-info-qom.h
+++ b/include/qemu/target-info-qom.h
@@ -26,5 +26,6 @@ typedef struct TargetInfoQomClass {
 OBJECT_DECLARE_TYPE(TargetInfoQom, TargetInfoQomClass, TARGET_INFO)
 
 void target_info_qom_set_target(void);
+void target_info_qom_set_target_from_name(const char *name);
 
 #endif /* QEMU_TARGET_INFO_QOM_H */
diff --git a/qemu-options.hx b/qemu-options.hx
index b8e2710a2cbd4..1d719b237cb60 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -24,6 +24,14 @@ SRST
     Display version information and exit
 ERST
 
+DEF("target", HAS_ARG, QEMU_OPTION_target, \
+    "-target target  selects the target architecture ('-target help' for list)\n",
+    QEMU_ARCH_ALL)
+SRST
+``-target target``
+    Selects target architecture ('-target help' for list)
+ERST
+
 DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
     "-machine [type=]name[,prop=value[,...]]\n"
     "                selects emulated machine ('-machine help' for list)\n"
diff --git a/system/vl.c b/system/vl.c
index bd7b9a8f14ac2..f889594c88d84 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -284,6 +284,15 @@ static QemuOptsList qemu_accel_opts = {
     },
 };
 
+static QemuOptsList qemu_target_opts = {
+    .name = "target",
+    .implied_opt_name = "target",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_target_opts.head),
+    .desc = {
+        { /* end of list */ },
+    },
+};
+
 static QemuOptsList qemu_boot_opts = {
     .name = "boot-opts",
     .implied_opt_name = "order",
@@ -2901,6 +2910,7 @@ void qemu_init(int argc, char **argv)
     qemu_add_opts(&qemu_semihosting_config_opts);
     qemu_add_opts(&qemu_fw_cfg_opts);
     qemu_add_opts(&qemu_action_opts);
+    qemu_add_opts(&qemu_target_opts);
     qemu_add_run_with_opts();
     module_call_init(MODULE_INIT_OPTS);
 
@@ -2910,7 +2920,26 @@ void qemu_init(int argc, char **argv)
     os_setup_limits();
 
     module_call_init(MODULE_INIT_TARGET_INFO);
-    target_info_qom_set_target();
+
+    /*
+     * Identify target: first from option, then from argv[0].
+     * This happens even before handling --help option, because it may contain
+     * entries that are target specific.
+     */
+    for (int idx = 1; idx < argc;) {
+        if (argv[idx][0] != '-') {
+            idx++;
+        } else {
+            const QEMUOption *popt = lookup_opt(argc, argv, &optarg, &idx);
+            if (popt->index == QEMU_OPTION_target) {
+                target_info_qom_set_target_from_name(optarg);
+                break;
+            }
+        }
+    }
+    if (!target_info()) {
+        target_info_qom_set_target();
+    }
 
     module_init_info(qemu_modinfo);
     module_allow_arch(target_name());
@@ -2958,6 +2987,9 @@ void qemu_init(int argc, char **argv)
                 exit(1);
             }
             switch(popt->index) {
+            case QEMU_OPTION_target:
+                /* handled previously, ignore it here */
+                break;
             case QEMU_OPTION_cpu:
                 /* hw initialization will check this */
                 cpu_option = optarg;
diff --git a/target-info-qom.c b/target-info-qom.c
index 7958a5cc685f9..5a3abeceb7672 100644
--- a/target-info-qom.c
+++ b/target-info-qom.c
@@ -9,6 +9,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qom/object.h"
+#include "qemu/error-report.h"
 #include "qemu/target-info-impl.h"
 #include "qemu/target-info-init.h"
 #include "qemu/target-info-qom.h"
@@ -73,6 +74,36 @@ void target_info_qom_set_target(void)
                                  "no target-info is available" :
                                  "more than one target-info is available");
     }
-
     target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info;
 }
+
+static void list_targets_available(void)
+{
+    printf("List of targets available:\n");
+    g_autoptr(GSList) targets = object_class_get_list_sorted(TYPE_TARGET_INFO, false);
+    for (GSList *elem = targets; elem; elem = elem->next) {
+        const TargetInfo *ti = TARGET_INFO_CLASS(elem->data)->target_info;
+        printf("- %s\n", ti->target_name);
+    }
+}
+
+void target_info_qom_set_target_from_name(const char *name)
+{
+    if (!strcmp(name, "help")) {
+        list_targets_available();
+        exit(0);
+    }
+
+    g_autoptr(GSList) targets = object_class_get_list(TYPE_TARGET_INFO, false);
+    for (GSList *elem = targets; elem; elem = elem->next) {
+        const TargetInfo *ti = TARGET_INFO_CLASS(elem->data)->target_info;
+        if (!strcmp(name, ti->target_name)) {
+            target_info_ptr = ti;
+            return;
+        }
+    }
+
+    error_report("target '%s' is not available", name);
+    list_targets_available();
+    exit(1);
+}

^ permalink raw reply related	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (11 preceding siblings ...)
  2026-08-23 15:07 ` [PATCH 12/12] meson: link ARM and RISC-V into qemu-system Yonggang Luo
@ 2026-08-24 16:36 ` Pierrick Bouvier
  2026-08-25 15:42 ` Daniel P. Berrangé
  2026-08-26 12:32 ` Daniel P. Berrangé
  14 siblings, 0 replies; 57+ messages in thread
From: Pierrick Bouvier @ 2026-08-24 16:36 UTC (permalink / raw)
  To: Yonggang Luo, qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

Hi Yonggang,

On 8/23/2026 8:07 AM, Yonggang Luo wrote:
> This series produces one qemu-system binary that can run ARM (32 and 64)
> and RISC-V (32 and 64, little- and big-endian TargetInfo). 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 mc->alias after the selected target is
>   applied.
> - 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.
>

Thanks for those patches, that's needed to be able to mix riscv and arm
base architectures.

> Target selection then has to work with more than one TargetInfo in the
> process:
> 
> - Register target-info-<name>-le and -be from one system
>   target-info-def.c unit, sharing arch fields. is_default follows
>   TARGET_BIG_ENDIAN so riscv/arm stay LE and ppc/s390x stay BE when
>   -target is omitted.

What is the goal here? Does it model something existing, or is it an
addition?

> - Parse -target before TargetInfo is fixed. Tokens are target_name or
>   target_name-be / -le. When -target is omitted, infer the token from
>   the program basename (strip .exe, longest registered suffix, drop a
>   trailing w for Windows GUI binaries).
> - 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 builds qemu-system (and qemu-systemw on Windows) from
> aarch64 common/system objects plus RISC-V arch objects, and installs
> qemu-system-{arm,aarch64,riscv32,riscv64} as symlinks so argv[0] still
> selects TargetInfo.
> 
> Examples:
> 
>   qemu-system -target aarch64 -M virt ...
>   qemu-system-riscv64 -M virt ...
> 
> A basename that matches no registered token falls through to the unique
> default. A combined binary with no suffix requires -target when more
> than one default TargetInfo is registered.
> 
> Based-on: <20260724000948.234657-1-pierrick.bouvier@oss.qualcomm.com>
>

thanks for posting this.

I was purposefully waiting to solve filtering issues for
machines/cpus/devices before sending any new command line switch, or
build system for single-binary to help focusing conversations. That
said, that's my personal approach and there is nothing wrong here.
Thanks for giving a glimpse to our community about what it will look like.

Regards,
Pierrick


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 09/12] target-info: register le and be TargetInfo variants
  2026-08-24 16:22   ` Pierrick Bouvier
@ 2026-08-24 19:01     ` Yonggang Luo
  2026-08-26 18:41       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 57+ messages in thread
From: Yonggang Luo @ 2026-08-24 19:01 UTC (permalink / raw)
  To: Pierrick Bouvier
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

[-- Attachment #1: Type: text/plain, Size: 9032 bytes --]

On Tue, Aug 25, 2026 at 12:22 AM Pierrick Bouvier <
pierrick.bouvier@oss.qualcomm.com> wrote:
>
> On 8/23/2026 8:07 AM, Yonggang Luo wrote:
> > - Register target-info-<name>-le and -be from one system
> >   target-info-def.c unit, sharing arch fields.
> > - Mark is_default from TARGET_BIG_ENDIAN so riscv/arm stay LE and
> >   ppc/s390x stay BE when -target is omitted.
> > - Pick the unique default in target_info_qom_set_target() when more
> >   than one TargetInfo is registered. Leave user-mode as a single
> >   target_info().
> >
> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> > ---
> >  include/qemu/target-info-impl.h |  6 ++++
> >  include/qemu/target-info-init.h | 29 +++++++++++++---
> >  target-info-def.c               | 61 +++++++++++++++++++++++++--------
> >  target-info-qom.c               | 33 ++++++++++++++----
> >  4 files changed, 104 insertions(+), 25 deletions(-)
> >
> > diff --git a/include/qemu/target-info-impl.h
b/include/qemu/target-info-impl.h
> > index de329ec2b86..b4222e4455e 100644
> > --- a/include/qemu/target-info-impl.h
> > +++ b/include/qemu/target-info-impl.h
> > @@ -23,6 +23,12 @@ typedef struct TargetInfo {
> >      const char *cpu_type;
> >      /* related to TARGET_BIG_ENDIAN definition */
> >      EndianMode endianness;
> > +    /*
> > +     * True on the endian variant that matches this translation unit's
> > +     * TARGET_BIG_ENDIAN. target_info_qom_set_target() uses this when
> > +     * more than one TargetInfo is registered and -target is omitted.
> > +     */
> > +    bool is_default;
> >      /*
> >       * runtime equivalent of
> >       *   TARGET_PAGE_BITS_VARY ? TARGET_PAGE_BITS_LEGACY :
TARGET_PAGE_BITS
> > diff --git a/include/qemu/target-info-init.h
b/include/qemu/target-info-init.h
> > index b7024c9faef..25d00adcc66 100644
> > --- a/include/qemu/target-info-init.h
> > +++ b/include/qemu/target-info-init.h
> > @@ -37,15 +37,34 @@ const TargetInfo *target_info(void)     \
> >  #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,
     \
> > +/*
> > + * QOM type names are target-info-<TARGET_NAME>-le and -be so both
> > + * endian variants can be registered from one system translation unit.
> > + */
> > +#define TARGET_INFO_QOM_SUFFIX_0 "-le"
> > +#define TARGET_INFO_QOM_SUFFIX_1 "-be"
> > +
> > +#define TARGET_INFO_QOM_NAME(sel)
      \
> > +    TYPE_TARGET_INFO "-" TARGET_NAME glue(TARGET_INFO_QOM_SUFFIX_, sel)
> > +
> > +#define TARGET_INFO_QOM_TYPEINFO(ti_var, sel)
      \
> > +static const TypeInfo glue(target_info_qom_type_, sel) = {
     \
> > +    .name = TARGET_INFO_QOM_NAME(sel),
     \
> >      .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)
> > +}
> > +
> > +#define target_info_init_le_be(ti_le, ti_be)
     \
> > +TARGET_INFO_QOM_TYPEINFO(ti_le, 0);
      \
> > +TARGET_INFO_QOM_TYPEINFO(ti_be, 1);
      \
> > +static void do_qemu_init_target_info(void)
     \
> > +{
      \
> > +    type_register_static(&target_info_qom_type_0);
     \
> > +    type_register_static(&target_info_qom_type_1);
     \
> > +}
      \
> > +module_init(do_qemu_init_target_info, MODULE_INIT_TARGET_INFO)
> >
> >  #endif /* CONFIG_USER_ONLY */
> >  #endif /* COMPILING_PER_TARGET */
> > diff --git a/target-info-def.c b/target-info-def.c
> > index 5d38e405735..6722c43a08f 100644
> > --- a/target-info-def.c
> > +++ b/target-info-def.c
> > @@ -28,39 +28,72 @@ QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) !=
sizeof(CPUState));
> >  QEMU_BUILD_BUG_ON(TARGET_PAGE_BITS < TARGET_PAGE_BITS_MIN);
> >  #endif
> >
> > -static const TargetInfo target_info_def = {
> > -    .target_name = TARGET_NAME,
> > -    .target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH),
> > -    .long_bits = TARGET_LONG_BITS,
> > -    .cpu_type = CPU_RESOLVING_TYPE,
> > -    .endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG :
ENDIAN_MODE_LITTLE,
> >  #ifdef TARGET_PAGE_BITS_VARY
> > -    .page_bits_vary = true,
> >  # ifdef TARGET_PAGE_BITS_LEGACY
> > +#  define TARGET_INFO_PAGE_BITS \
> > +    .page_bits_vary = true, \
> >      .page_bits_init = TARGET_PAGE_BITS_LEGACY,
> > +# else
> > +#  define TARGET_INFO_PAGE_BITS \
> > +    .page_bits_vary = true,
> >  # endif
> >  #else
> > -    .page_bits_vary = false,
> > +# define TARGET_INFO_PAGE_BITS \
> > +    .page_bits_vary = false, \
> >      .page_bits_init = TARGET_PAGE_BITS,
> >  #endif
> >
> >  #ifndef CONFIG_USER_ONLY
> >  # ifdef CONFIG_MULTIPROCESS
> > -    .config_multiprocess = true,
> > +#  define TARGET_INFO_CONFIG_MULTIPROCESS .config_multiprocess = true,
> >  # else
> > -    .config_multiprocess = false,
> > +#  define TARGET_INFO_CONFIG_MULTIPROCESS .config_multiprocess = false,
> >  # endif
> >  # ifdef CONFIG_NITRO
> > -    .config_nitro = true,
> > +#  define TARGET_INFO_CONFIG_NITRO .config_nitro = true,
> >  # else
> > -    .config_nitro = false,
> > +#  define TARGET_INFO_CONFIG_NITRO .config_nitro = false,
> >  # endif
> >  # ifdef CONFIG_XEN
> > -    .config_xen = true,
> > +#  define TARGET_INFO_CONFIG_XEN .config_xen = true,
> >  # else
> > -    .config_xen = false,
> > +#  define TARGET_INFO_CONFIG_XEN .config_xen = false,
> >  # endif
> > +# define TARGET_INFO_CONFIG \
> > +    TARGET_INFO_CONFIG_MULTIPROCESS \
> > +    TARGET_INFO_CONFIG_NITRO \
> > +    TARGET_INFO_CONFIG_XEN
> > +#else
> > +# define TARGET_INFO_CONFIG
> >  #endif
> > +
> > +#define TARGET_INFO_COMMON
     \
> > +    .target_name = TARGET_NAME,
      \
> > +    .target_arch = glue(SYS_EMU_TARGET_, TARGET_ARCH),
     \
> > +    .long_bits = TARGET_LONG_BITS,
     \
> > +    .cpu_type = CPU_RESOLVING_TYPE,
      \
> > +    TARGET_INFO_PAGE_BITS
      \
> > +    TARGET_INFO_CONFIG
> > +
> > +#ifdef CONFIG_USER_ONLY
> > +static const TargetInfo target_info_def = {
> > +    TARGET_INFO_COMMON
> > +    .endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG :
ENDIAN_MODE_LITTLE,
> >  };
> >
> >  target_info_init(target_info_def)
> > +#else
> > +static const TargetInfo target_info_le = {
> > +    TARGET_INFO_COMMON
> > +    .endianness = ENDIAN_MODE_LITTLE,
> > +    .is_default = !TARGET_BIG_ENDIAN,
> > +};
> > +
> > +static const TargetInfo target_info_be = {
> > +    TARGET_INFO_COMMON
> > +    .endianness = ENDIAN_MODE_BIG,
> > +    .is_default = TARGET_BIG_ENDIAN,
> > +};
> > +
> > +target_info_init_le_be(target_info_le, target_info_be)
> > +#endif
> > diff --git a/target-info-qom.c b/target-info-qom.c
> > index 68ad734049c..2c1c57b05fd 100644
> > --- a/target-info-qom.c
> > +++ b/target-info-qom.c
> > @@ -90,13 +90,34 @@ const TargetInfo *target_info(void)
> >  void target_info_qom_set_target(void)
> >  {
> >      g_autoptr(GSList) targets =
object_class_get_list(TYPE_TARGET_INFO, false);
> > -
> > +    const TargetInfo *chosen = NULL;
> >      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");
> > +    size_t num_default = 0;
> > +
> > +    if (num_found == 0) {
> > +        error_setg(&error_fatal, "no target-info is available");
> > +    }
> > +
> > +    if (num_found == 1) {
> > +        target_info_ptr =
TARGET_INFO_CLASS(targets->data)->target_info;
> > +        return;
> > +    }
> > +
> > +    for (GSList *l = targets; l; l = l->next) {
> > +        const TargetInfo *ti = TARGET_INFO_CLASS(l->data)->target_info;
> > +
> > +        if (ti->is_default) {
> > +            num_default++;
> > +            chosen = ti;
> > +        }
> > +    }
> > +
> > +    if (num_default != 1) {
> > +        error_setg(&error_fatal, num_default == 0 ?
> > +                                 "no default target-info is available"
:
> > +                                 "more than one default target-info "
> > +                                 "is available");
> >      }
> >
> > -    target_info_ptr = TARGET_INFO_CLASS(targets->data)->target_info;
> > +    target_info_ptr = chosen;
> >  }
>
> Is it representing existing targets, or adding new ones per endianness?
> I'm not sure if the goal is to add new binaries, or mimic existing ones
> with specific parameters.


Is optional now, not a force requirement, this is needed when we use GDB
debug qemu riscv-be, as gdbstub are depends on target_info


--
         此致
礼
罗勇刚
Yours
    sincerely,
Yonggang Luo

[-- Attachment #2: Type: text/html, Size: 12851 bytes --]

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 12/12] meson: link ARM and RISC-V into qemu-system
  2026-08-24 16:20   ` Pierrick Bouvier
@ 2026-08-24 19:04     ` Yonggang Luo
  2026-08-26 13:00     ` Daniel P. Berrangé
  1 sibling, 0 replies; 57+ messages in thread
From: Yonggang Luo @ 2026-08-24 19:04 UTC (permalink / raw)
  To: Pierrick Bouvier
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

[-- Attachment #1: Type: text/plain, Size: 9277 bytes --]

Thanks, a lot simpler, you can pick my patches(you think is good) into your
patch series and repost as a new version, so the review process is easier.

On Tue, Aug 25, 2026 at 12:20 AM Pierrick Bouvier <
pierrick.bouvier@oss.qualcomm.com> wrote:
>
> On 8/23/2026 8:07 AM, Yonggang Luo wrote:
> > - Build qemu-system (and qemu-systemw on Windows) from aarch64
> >   common/system objects plus RISC-V arch objects taken from the
> >   existing riscv64 lib.
> > - Pull 32-bit TargetInfo and 32-only boards from the arm/riscv32
> >   libs so hw/arm and target/riscv are not compiled twice.
> > - Skip linking qemu-system-{arm,aarch64,riscv32,riscv64} and the
> >   Windows *w variants; symlink those names to qemu-system so
> >   argv[0] still selects TargetInfo.
> >
> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> > ---
> >  meson.build | 156 +++++++++++++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 147 insertions(+), 9 deletions(-)
> >
> > diff --git a/meson.build b/meson.build
> > index 449d50f2983..b4f435f6a22 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -4250,6 +4250,10 @@ endif
> >
> >  traceable = []
> >  emulators = {}
> > +target_softmmu = {}
> > +combo_softmmu = ['aarch64-softmmu', 'arm-softmmu', 'riscv32-softmmu',
'riscv64-softmmu']
> > +have_qemu_system_combo = ('aarch64-softmmu' in target_dirs
> > +                          and 'riscv64-softmmu' in target_dirs)
> >  foreach target : target_dirs
> >    config_target = config_target_mak[target]
> >    target_name = config_target['TARGET_NAME']
> > @@ -4399,20 +4403,37 @@ foreach target : target_dirs
> >                   c_args: c_args,
> >                   build_by_default: false)
> >
> > +  if target in combo_softmmu
> > +    target_softmmu += {target: {
> > +      'lib': lib,
> > +      'arch_srcs': arch_srcs,
> > +      'arch_deps': arch_deps,
> > +      'c_args': c_args,
> > +      'link_args': link_args,
> > +      'target_stubs': target_stubs,
> > +      'main_rs': main_rs,
> > +      'config_target': config_target,
> > +      'target_base_arch': target_base_arch,
> > +    }}
> > +  endif
> > +
> >    if target.endswith('-softmmu')
> > -    execs = [{
> > -      'name': 'qemu-system-' + target_name,
> > -      'win_subsystem': 'console',
> > -      'sources': [main_rs, files('system/main.c')],
> > -      'dependencies': [sdl, target_stubs],
> > -    }]
> > -    if host_os == 'windows' and (sdl.found() or gtk.found())
> > +    execs = []
> > +    if not (have_qemu_system_combo and target in combo_softmmu)
> >        execs += [{
> > -        'name': 'qemu-system-' + target_name + 'w',
> > -        'win_subsystem': 'windows',
> > +        'name': 'qemu-system-' + target_name,
> > +        'win_subsystem': 'console',
> >          'sources': [main_rs, files('system/main.c')],
> >          'dependencies': [sdl, target_stubs],
> >        }]
> > +      if host_os == 'windows' and (sdl.found() or gtk.found())
> > +        execs += [{
> > +          'name': 'qemu-system-' + target_name + 'w',
> > +          'win_subsystem': 'windows',
> > +          'sources': [main_rs, files('system/main.c')],
> > +          'dependencies': [sdl, target_stubs],
> > +        }]
> > +      endif
> >      endif
> >      if get_option('fuzzing')
> >        specific_fuzz = specific_fuzz_ss.apply(config_target, strict:
false)
> > @@ -4481,6 +4502,123 @@ foreach target : target_dirs
> >    endforeach
> >  endforeach
> >
> > +# Combined ARM + RISC-V system emulator (32 and 64).
> > +# Common/system objects come from aarch64. RISC-V arch objects come
> > +# from the existing riscv64 lib. 32-bit TargetInfo and 32-only boards
> > +# come from the arm/riscv32 libs. Per-target qemu-system-* names are
> > +# symlinks to qemu-system (argv[0] selects TargetInfo).
> > +if have_qemu_system_combo
> > +  a64 = target_softmmu['aarch64-softmmu']
> > +  rv = target_softmmu['riscv64-softmmu']
> > +  extra_objs = []
> > +  target_info_def = files('target-info-def.c')
> > +  foreach spec : [[common_ss, common_all], [system_ss, libsystem]]
> > +    rv_src = spec[0].apply(rv['config_target'], strict: false)
> > +    a64_src = spec[0].apply(a64['config_target'], strict: false)
> > +    extra = []
> > +    foreach f : rv_src.sources()
> > +      if f not in a64_src.sources() and not
f.full_path().endswith('_stubs.c')
> > +        extra += f
> > +      endif
> > +    endforeach
> > +    if extra.length() > 0
> > +      extra_objs += spec[1].extract_objects(extra)
> > +    endif
> > +  endforeach
> > +  rv_base = rv['target_base_arch']
> > +  if rv_base in target_common_arch_libs
> > +    src = target_common_arch[rv_base].apply(rv['config_target'],
strict: false)
> > +    extra_objs +=
target_common_arch_libs[rv_base].extract_objects(src.sources())
> > +  endif
> > +  if rv_base in target_common_system_arch_libs
> > +    src =
target_common_system_arch[rv_base].apply(rv['config_target'], strict: false)
> > +    extra_objs +=
target_common_system_arch_libs[rv_base].extract_objects(src.sources())
> > +  endif
> > +  foreach pair : [['arm-softmmu', 'aarch64-softmmu'],
['riscv32-softmmu', 'riscv64-softmmu']]
> > +    t32 = pair[0]
> > +    t64 = pair[1]
> > +    if t32 in target_softmmu
> > +      extra_objs +=
target_softmmu[t32]['lib'].extract_objects(target_info_def)
> > +      base32 = target_softmmu[t32]['target_base_arch']
> > +      if base32 in hw_arch
> > +        hw32 =
hw_arch[base32].apply(target_softmmu[t32]['config_target'], strict: false)
> > +        hw64 =
hw_arch[base32].apply(target_softmmu[t64]['config_target'], strict: false)
> > +        extra_hw = []
> > +        foreach f : hw32.sources()
> > +          if f not in hw64.sources()
> > +            extra_hw += f
> > +          endif
> > +        endforeach
> > +        if extra_hw.length() > 0
> > +          extra_objs +=
target_softmmu[t32]['lib'].extract_objects(extra_hw)
> > +        endif
> > +      endif
> > +    endif
> > +  endforeach
> > +  combo_objects = extra_objs
> > +  combo_objects += a64['lib'].extract_all_objects(recursive: true)
> > +  combo_objects += rv['lib'].extract_objects(rv['arch_srcs'])
> > +  combo_deps = a64['arch_deps'] + rv['arch_deps'] + [sdl,
a64['target_stubs'], rv['target_stubs']]
> > +  if 'arm-softmmu' in target_softmmu
> > +    combo_deps += target_softmmu['arm-softmmu']['arch_deps']
> > +  endif
> > +  if 'riscv32-softmmu' in target_softmmu
> > +    combo_deps += target_softmmu['riscv32-softmmu']['arch_deps']
> > +  endif
> > +  combo_execs = [{
> > +    'name': 'qemu-system',
> > +    'win_subsystem': 'console',
> > +  }]
> > +  if host_os == 'windows' and (sdl.found() or gtk.found())
> > +    combo_execs += [{
> > +      'name': 'qemu-systemw',
> > +      'win_subsystem': 'windows',
> > +    }]
> > +  endif
> > +  combo_exe_suffix = host_os == 'windows' ? '.exe' : ''
> > +  combo_alias_py = 'import os, sys; src, dst = sys.argv[1:3];
os.path.exists(dst) and os.remove(dst); os.symlink(os.path.basename(src),
dst)'
> > +  foreach exe : combo_execs
> > +    emulator = executable(exe['name'], [a64['main_rs'],
files('system/main.c')],
> > +               install: true,
> > +               c_args: a64['c_args'],
> > +               dependencies: combo_deps,
> > +               objects: combo_objects,
> > +               link_depends: [block_syms, qemu_syms],
> > +               link_args: a64['link_args'],
> > +               win_subsystem: exe['win_subsystem'])
> > +    emulators += {exe['name']: emulator}
> > +    traceable += [{
> > +      'exe': exe['name'],
> > +      'probe-prefix': 'qemu.system.multi',
> > +    }]
> > +    foreach t : combo_softmmu
> > +      if t not in target_softmmu
> > +        continue
> > +      endif
> > +      tname = target_softmmu[t]['config_target']['TARGET_NAME']
> > +      if exe['name'] == 'qemu-systemw'
> > +        alias = 'qemu-system-' + tname + 'w'
> > +      else
> > +        alias = 'qemu-system-' + tname
> > +      endif
> > +      alias_tgt = custom_target(alias,
> > +                                input: emulator,
> > +                                output: alias + combo_exe_suffix,
> > +                                command: [python, '-c',
combo_alias_py, '@INPUT@', '@OUTPUT@'],
> > +                                build_by_default: true,
> > +                                install: false)
> > +      emulators += {alias: alias_tgt}
> > +      install_symlink(alias + combo_exe_suffix,
> > +                      pointing_to: exe['name'] + combo_exe_suffix,
> > +                      install_dir: get_option('bindir'))
> > +      traceable += [{
> > +        'exe': alias,
> > +        'probe-prefix': 'qemu.system.' + tname,
> > +      }]
> > +    endforeach
> > +  endforeach
> > +endif
> > +
> >  # Other build targets
> >
> >  if get_option('plugins')
>
> Please find attached a much simpler implementation, which only requires
> a single line update as we add new targets in single-binary.
>
> Regards,
> Pierrick



--
         此致
礼
罗勇刚
Yours
    sincerely,
Yonggang Luo

[-- Attachment #2: Type: text/html, Size: 12567 bytes --]

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (12 preceding siblings ...)
  2026-08-24 16:36 ` [PATCH 00/12] single-binary: " Pierrick Bouvier
@ 2026-08-25 15:42 ` Daniel P. Berrangé
  2026-08-25 16:55   ` Yonggang Luo
  2026-08-25 17:11   ` Yonggang Luo
  2026-08-26 12:32 ` Daniel P. Berrangé
  14 siblings, 2 replies; 57+ messages in thread
From: Daniel P. Berrangé @ 2026-08-25 15:42 UTC (permalink / raw)
  To: Yonggang Luo
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, Pierrick Bouvier, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Sun, Aug 23, 2026 at 11:07:18PM +0800, Yonggang Luo wrote:
> This series produces one qemu-system binary that can run ARM (32 and 64)
> and RISC-V (32 and 64, little- and big-endian TargetInfo). 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/

Do you have a public git branch somewhere with this series ? I'm
having trouble getting either this series or Pierrick's to cleanly
apply at any point to test 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 :|



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-25 15:42 ` Daniel P. Berrangé
@ 2026-08-25 16:55   ` Yonggang Luo
  2026-08-25 17:22     ` Daniel P. Berrangé
  2026-08-25 17:11   ` Yonggang Luo
  1 sibling, 1 reply; 57+ messages in thread
From: Yonggang Luo @ 2026-08-25 16:55 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, Pierrick Bouvier, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

[-- Attachment #1: Type: text/plain, Size: 1256 bytes --]

On Tue, Aug 25, 2026 at 11:42 PM Daniel P. Berrangé <berrange@redhat.com>
wrote:
>
> On Sun, Aug 23, 2026 at 11:07:18PM +0800, Yonggang Luo wrote:
> > This series produces one qemu-system binary that can run ARM (32 and 64)
> > and RISC-V (32 and 64, little- and big-endian TargetInfo). 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/
>
> Do you have a public git branch somewhere with this series ? I'm
> having trouble getting either this series or Pierrick's to cleanly
> apply at any point to test it.


https://patchew.org/QEMU/20260823150731.896-1-luoyonggang@gmail.com/

you can use git patchew do it

git fetch https://github.com/patchew-project/qemu tags/patchew/
20260823150731.896-1-luoyonggang@gmail.com

a>
>
> 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

[-- Attachment #2: Type: text/html, Size: 2091 bytes --]

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-25 15:42 ` Daniel P. Berrangé
  2026-08-25 16:55   ` Yonggang Luo
@ 2026-08-25 17:11   ` Yonggang Luo
  1 sibling, 0 replies; 57+ messages in thread
From: Yonggang Luo @ 2026-08-25 17:11 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, Pierrick Bouvier, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

[-- Attachment #1: Type: text/plain, Size: 1129 bytes --]

The github branch I built locally

https://github.com/lygstate/qemu/tree/s11.1-riscv-arm

On Tue, Aug 25, 2026 at 11:42 PM Daniel P. Berrangé <berrange@redhat.com>
wrote:
>
> On Sun, Aug 23, 2026 at 11:07:18PM +0800, Yonggang Luo wrote:
> > This series produces one qemu-system binary that can run ARM (32 and 64)
> > and RISC-V (32 and 64, little- and big-endian TargetInfo). 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/
>
> Do you have a public git branch somewhere with this series ? I'm
> having trouble getting either this series or Pierrick's to cleanly
> apply at any point to test 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

[-- Attachment #2: Type: text/html, Size: 1825 bytes --]

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-25 16:55   ` Yonggang Luo
@ 2026-08-25 17:22     ` Daniel P. Berrangé
  0 siblings, 0 replies; 57+ messages in thread
From: Daniel P. Berrangé @ 2026-08-25 17:22 UTC (permalink / raw)
  To: Yonggang Luo
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, Pierrick Bouvier, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Wed, Aug 26, 2026 at 12:55:09AM +0800, Yonggang Luo wrote:
> On Tue, Aug 25, 2026 at 11:42 PM Daniel P. Berrangé <berrange@redhat.com>
> wrote:
> >
> > On Sun, Aug 23, 2026 at 11:07:18PM +0800, Yonggang Luo wrote:
> > > This series produces one qemu-system binary that can run ARM (32 and 64)
> > > and RISC-V (32 and 64, little- and big-endian TargetInfo). 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/
> >
> > Do you have a public git branch somewhere with this series ? I'm
> > having trouble getting either this series or Pierrick's to cleanly
> > apply at any point to test it.
> 
> 
> https://patchew.org/QEMU/20260823150731.896-1-luoyonggang@gmail.com/
> 
> you can use git patchew do it
> 
> git fetch https://github.com/patchew-project/qemu tags/patchew/
> 20260823150731.896-1-luoyonggang@gmail.com

Oh yes, thanks for the reminder about patchew, that does the job.

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] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
                   ` (13 preceding siblings ...)
  2026-08-25 15:42 ` Daniel P. Berrangé
@ 2026-08-26 12:32 ` Daniel P. Berrangé
  2026-08-26 13:40   ` Mark Cave-Ayland
                     ` (2 more replies)
  14 siblings, 3 replies; 57+ messages in thread
From: Daniel P. Berrangé @ 2026-08-26 12:32 UTC (permalink / raw)
  To: Yonggang Luo
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, Pierrick Bouvier, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Sun, Aug 23, 2026 at 11:07:18PM +0800, Yonggang Luo wrote:

snip,

..to comment just on the end result for now..

> The last patch builds qemu-system (and qemu-systemw on Windows) from
> aarch64 common/system objects plus RISC-V arch objects, and installs
> qemu-system-{arm,aarch64,riscv32,riscv64} as symlinks so argv[0] still
> selects TargetInfo.
> 
> Examples:
> 
>   qemu-system -target aarch64 -M virt ...
>   qemu-system-riscv64 -M virt ...
> 
> A basename that matches no registered token falls through to the unique
> default. A combined binary with no suffix requires -target when more
> than one default TargetInfo is registered.

In testing and comparing  the new qemu-system-riscv64 symlink
to qemu-system vs the current standalone qemu-system-riscv64
binary there are some significant user visible changes.

The simplest is 'qom-list-types' went from reporting approx
770 classes, to reporting approx 1530 classes. IOW, the
qemu-system-riscv64 binary is now reporting supporting for
all the classes that were unique to arm.

The '-device help' output similarly shows a great many more
devices

TL;DR introspecting qemu-system-riscv64 is no longer accurate
wrt riscv64 capabilities. 

This is not suprising, since we register all TypeInfo meaning
we get all QOM classes present. Some of Pierricks patches try
to filter places which iterate over classes, but this does not
have full coverage.


I think this is probably also what leads to the increased RAM
usage in qemu-system-riscv64. Starting

  qemu-system-riscv64 -nodefaults -display none -M none

shows an increase in RAM usage from  17.3 to 20.7 MB which
is about 15% increase. NB this is dirty, private RAM per
process. The shared RAM pages also increase but that's not
a concern since they're common to all QEMU processes.

qemu-system-aarch64 shows a much smaller RAM increase, since
it only grew from 1430 classes to 1530 classes.

We have many more target though, so if we assume the end
point where every single target is unified, the the union
of all classes for all targets comes to approx 3600.

My guesstimate is that would mean a memory increase for
qemu-system-riscv64 from 17.3 to 39.9 MB, which is a
72% increase.

In absolute terms this is still modest, but for deployments
with large VM counts  and small RAM sizes, that gets to be
significant.


None of this means single binary is a bad idea.


My main takeaway is that we're creating uneccessary work
for ourselves by trying to make 'qemu-sytem' identical
in behaviour to qemu-system-$TARGET.

The complex filtering patches / QOM interfaces that I
found uncomfortable in Pierrick's base series are largely
around the filtering needed to simulate qemu-system-$TARGET,
and they're still incomplete. I don't have high confidence
in our ability to avoid regressions if we go route this
route.


IMHO we should make a clean break with the past. Leave
the existing qemu-system-$TARGET binaries being built
from the same pieces they are today, such that there
is better confidence that we are not making behavioural
changes to them.


qemu-system should be built alongside qemu-system-$TARGET
and offer new semantics where it is documented as exposing
everything from all targets whenever introspected and does
not apply target type or target Kconfig filtering to inputs/
outputs. 

We still get the benefit of only building most  .o files
once, so keeping qemu-system-$TARGET is only a small
overhead in the final step of linking everything together.


qemu-system will still have the increased memory overhead
but that's fine as qemu-system-$TARGET will be unaffected.
We can tackle the memory overhead of qemu-system at our
leisure through use of loadable modules, and thus not have
that as a task to think about today.


With the clean break with the past, we also have the
ability to tackle various long standing design mistakes
present in qemu-system-$TARGET instead of carrying them
over into the new binary.

Specifically

 * -nodefaults should become the default
 
 * All CLI args should be processed in order from
   the command line, so we eliminate the nonsense
   where we process some -object, then -chardev,
   then more -object through hand crafted deps

 * No default machine type

 * Drop all legacy syntax so we only have a single
   QAPI based way of configuring.
   eg drop -hda, -hdb, -cdrom, -drive, etc
      only keeping -blockdev
   eg drop -mon, -monitor, -qmp, etc only
      keeping -object

We don't have to do all that straightaway. If we declare
qemu-system "experimental" initially we can iterate on
that intentionally breaking compat in releases, without
any impact on qemu-system-$TARGET.

Avoiding the back compat task will give us more flexibility
with the follow on work when people come to create new
machine types with heterogenous CPU 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 :|



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 10/12] target-info: add -target and program-name selection
  2026-08-23 15:07 ` [PATCH 10/12] target-info: add -target and program-name selection Yonggang Luo
  2026-08-24 16:24   ` Pierrick Bouvier
@ 2026-08-26 12:46   ` Daniel P. Berrangé
  2026-08-26 18:13     ` Pierrick Bouvier
  2026-08-27 12:25     ` Daniel P. Berrangé
  1 sibling, 2 replies; 57+ messages in thread
From: Daniel P. Berrangé @ 2026-08-26 12:46 UTC (permalink / raw)
  To: Yonggang Luo
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, Pierrick Bouvier, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Sun, Aug 23, 2026 at 11:07:28PM +0800, Yonggang Luo wrote:
> - Parse -target before TargetInfo is fixed; CLI overrides the program
>   basename.
> - Tokens are target_name or target_name-be / -le; -target help lists
>   registered names in sorted order.
> - When -target is omitted, infer the token from g_get_prgname(): strip
>   .exe, take the longest dash-separated registered suffix, and retry
>   without a trailing w for Windows GUI binaries.
> - A basename that matches no registered token falls through to the
>   unique default. Combined binaries with no suffix require -target
>   when more than one default TargetInfo is registered.

IMHO this -target argument and the target interference from
program name is a mistaken direction.  We're being led off
course by the attempt to make the new qemu-system be identical
to qemu-system-$TARGET.

If we ignore historical compat and treat qemu-system as a
clean break, then I'd suggest that 'target' is not a concept
to be exposed to the user at all.

The user cares about the machine (and CPUs) they want to run,
and their choice in this respect is what should determine the
target(s) QEMU needs to enable. We should take

  qemu-system --machine vexpress-a15

that tells us we need the arm target. If we need to distinguish
arm7 vs aarch64, then the choice of -cpu should determine 32
bs 64 bit.

This extends better into the future world where we have
machine type that could involve CPUs from multiple targets.

IOW machine config option / QOM class is what we should pivot
off rather than a global target config option.

This likely implies that the MachineClass should gain a class
method to query the QEMU_ARCH_XXXX bitmask required. Initially
restricted to only a single target, so you can wire that through
to the current global target info at startup. Later expanded to
support multiple concurrent 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 :|



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 03/12] hw/arm/virt: use unique QOM name and target filter
  2026-08-23 15:07 ` [PATCH 03/12] hw/arm/virt: " Yonggang Luo
@ 2026-08-26 12:49   ` Daniel P. Berrangé
  0 siblings, 0 replies; 57+ messages in thread
From: Daniel P. Berrangé @ 2026-08-26 12:49 UTC (permalink / raw)
  To: Yonggang Luo
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, Pierrick Bouvier, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Sun, Aug 23, 2026 at 11:07:21PM +0800, Yonggang Luo wrote:
> - Set TYPE_VIRT_MACHINE to MACHINE_TYPE_NAME("arm-virt") so ARM virt
>   no longer collides with other virt-machine types in one process.
> - Register TYPE_TARGET_SPECIFIC with is_available = target_base_arm on
>   the abstract parent.
> - Keep -machine virt via mc->alias on the latest versioned machine.

While this solves the headline QOM name clash today, it misses
the bigger picture - the arm virt machine is versioned:

$ qemu-system-aarch64 -M help | grep ^virt
virt-10.0            QEMU 10.0 ARM Virtual Machine
virt-10.1            QEMU 10.1 ARM Virtual Machine
virt                 QEMU 10.2 ARM Virtual Machine (alias of virt-10.2)
virt-10.2            QEMU 10.2 ARM Virtual Machine
virt-5.0             QEMU 5.0 ARM Virtual Machine (deprecated)
virt-5.1             QEMU 5.1 ARM Virtual Machine (deprecated)
virt-5.2             QEMU 5.2 ARM Virtual Machine (deprecated)
virt-6.0             QEMU 6.0 ARM Virtual Machine (deprecated)
virt-6.1             QEMU 6.1 ARM Virtual Machine (deprecated)
virt-6.2             QEMU 6.2 ARM Virtual Machine (deprecated)
virt-7.0             QEMU 7.0 ARM Virtual Machine (deprecated)
virt-7.1             QEMU 7.1 ARM Virtual Machine (deprecated)
virt-7.2             QEMU 7.2 ARM Virtual Machine (deprecated)
virt-8.0             QEMU 8.0 ARM Virtual Machine
virt-8.1             QEMU 8.1 ARM Virtual Machine
virt-8.2             QEMU 8.2 ARM Virtual Machine
virt-9.0             QEMU 9.0 ARM Virtual Machine
virt-9.1             QEMU 9.1 ARM Virtual Machine
virt-9.2             QEMU 9.2 ARM Virtual Machine


At some point the riscv64 virt machine is very likely to become
versioned too at which point all the versioned machines will
clash.

IOW, the change to unique naming needs to be applied to all virt
machine versions, not just the unversioned name.


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] 57+ messages in thread

* Re: [PATCH 12/12] meson: link ARM and RISC-V into qemu-system
  2026-08-24 16:20   ` Pierrick Bouvier
  2026-08-24 19:04     ` Yonggang Luo
@ 2026-08-26 13:00     ` Daniel P. Berrangé
  2026-08-26 17:40       ` Pierrick Bouvier
  1 sibling, 1 reply; 57+ messages in thread
From: Daniel P. Berrangé @ 2026-08-26 13:00 UTC (permalink / raw)
  To: Pierrick Bouvier
  Cc: Yonggang Luo, qemu-devel, Xianglai Li, Alistair Francis,
	Chinmay Rath, Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu,
	Eric Farman, Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Mon, Aug 24, 2026 at 09:20:38AM -0700, Pierrick Bouvier wrote:
> On 8/23/2026 8:07 AM, Yonggang Luo wrote:
> > - Build qemu-system (and qemu-systemw on Windows) from aarch64
> >   common/system objects plus RISC-V arch objects taken from the
> >   existing riscv64 lib.
> > - Pull 32-bit TargetInfo and 32-only boards from the arm/riscv32
> >   libs so hw/arm and target/riscv are not compiled twice.
> > - Skip linking qemu-system-{arm,aarch64,riscv32,riscv64} and the
> >   Windows *w variants; symlink those names to qemu-system so
> >   argv[0] still selects TargetInfo.
> > 
> > Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> > ---
> >  meson.build | 156 +++++++++++++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 147 insertions(+), 9 deletions(-)

I think this approach of taking common/system from aarch64
and adding in riscv specific objects only works by luck.

That's not obvious from your patch, but Pierrick's counterproposal
below will expose it with a little  tweak....


> From 6261b0c255e1a8f0df2b41928b8dfb365d0fa488 Mon Sep 17 00:00:00 2001
> From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
> Date: Tue, 14 Apr 2026 10:56:15 -0700
> Subject: [PATCH] meson: build single binary
> 
> This is not built by default.
> Build with: ninja -C build qemu-system
> 
> All available *-softmmu targets are aggregated, ./configure
> --target-list can be used to restrict which targets are included.
> 
> In case user has targets that are not supported, we emit an error
> message when build qemu-system target. This way, it's not necessary to
> have a custom configure flag, and qemu-system can live next to existing
> binaries without complexifying the workflow more than it is already.
> 
> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
> ---
>  meson.build | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 48 insertions(+)
> 
> diff --git a/meson.build b/meson.build
> index 553df3e7f053..4a31a520d9eb 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -4264,6 +4264,9 @@ if host_os == 'darwin'
>  endif
>  
>  traceable = []
> +single_binary_libs = []
> +single_binary_deps = []
> +single_binary_crates = []
>  emulators = {}
>  foreach target : target_dirs
>    config_target = config_target_mak[target]
> @@ -4419,6 +4422,10 @@ foreach target : target_dirs
>                   build_by_default: false)
>  
>    if target.endswith('-softmmu')
> +    single_binary_libs += lib
> +    single_binary_deps += arch_deps
> +    single_binary_deps += target_stubs
> +    single_binary_crates += main_rs
>      execs = [{
>        'name': 'qemu-system-' + target_name,
>        'win_subsystem': 'console',
> @@ -4500,6 +4507,47 @@ foreach target : target_dirs
>    endforeach
>  endforeach
>  
> +single_binary_objects = []
> +foreach lib: single_binary_libs
> +  single_binary_objects += lib.extract_all_objects(recursive: true)
> +endforeach
> +
> +single_binary_link_args = emulator_link_args
> +single_binary_link_args += enable_modules ? ['@block.syms', '@qemu.syms'] : []
> +
> +supported_targets = [
> +  'aarch64-softmmu',
> +  'arm-softmmu',
> +]

Adding in riscv64-softmmu to this list and building with
configure --target-list=aarch64-softmmu,riscv64-softmmu
will fail with this meson approach.

Specifically we'll hit duplicate symbols to to taking
different KConfig branches, resulting in building in
both the real impl and the stubs:

  /usr/bin/ld.bfd: libsystem.a.p/hw_pci-bridge_pci_expander_bridge_stubs.c.o: in function `pxb_cxl_hook_up_registers':
/home/berrange/src/virt/qemu/build-alt/../hw/pci-bridge/pci_expander_bridge_stubs.c:14: multiple definition of `pxb_cxl_hook_up_registers'; libsystem.a.p/hw_pci-bridge_pci_expander_bridge.c.o:/home/berrange/src/virt/qemu/build-alt/../hw/pci-bridge/pci_expander_bridge.c:214: first defined here

The problem is that aarch64 enables CONFIG_PXB and
riscv64 does not.

Yonggang's patch only worked by luck since it preferred
to the common system objects from aarch64 and thus kept
the real PXB impl. If Yonggang had instead used common
system objects from riscv64, the qemu-system would have
lost the PXB impl and got a stub.

This is unfixable if both targets have some Kconfigs
that the other target does not.

So to be able to build qemu-system, we can't simply
pull in the union of objects from each architecture
qemu-system-$TARGET binary. 

Instead we need to setup a new Kconfig specifically
for qemu-system, which is the combination of all
Kconfigs from each target. Then derive a new list
of objects from that.  This shouldn't involve building
any more .o files, just means we build an accurate
list of what .o files we need.

> +unsupported_targets = []
> +foreach target : target_dirs
> +  if target.endswith('-softmmu') and target not in supported_targets
> +    unsupported_targets += target
> +  endif
> +endforeach
> +
> +if unsupported_targets.length() == 0
> +  executable('qemu-system',
> +             sources: [single_binary_crates, files('system/main.c')],
> +             dependencies: single_binary_deps,
> +             objects: single_binary_objects,
> +             link_depends: [block_syms, qemu_syms],
> +             link_args: single_binary_link_args,
> +             build_by_default: false)
> +else
> +  error_str = f'''qemu-system only support targets:
> +@supported_targets@

With the Kconfig union problem solved, IMHO we should unconditionally
always build the 'qemu-system' binary. If there are targets that
do not yet support the single bniary concept that's fine, just ignore
them. qemu-system-$TARGET will still be built for everything, and
qemu-system only needs to include what's currently possible.


> +
> +unsupported targets:
> +@unsupported_targets@
> +
> +use ./configure --target-list= to choose list of targets'''
> +  t = custom_target(command: ['sh', '-c', 'echo "' + error_str + '" && exit 1'],
> +                    output: 'none',
> +                    build_by_default: false)
> +  alias_target('qemu-system', t)
> +endif
> +
>  # Other build targets
>  
>  if get_option('plugins')


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] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-26 12:32 ` Daniel P. Berrangé
@ 2026-08-26 13:40   ` Mark Cave-Ayland
  2026-08-26 13:58     ` Daniel P. Berrangé
                       ` (2 more replies)
  2026-08-26 18:35   ` Pierrick Bouvier
  2026-08-27 17:59   ` Paolo Bonzini
  2 siblings, 3 replies; 57+ messages in thread
From: Mark Cave-Ayland @ 2026-08-26 13:40 UTC (permalink / raw)
  To: Daniel P. Berrangé, Yonggang Luo
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, Pierrick Bouvier, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 26/08/2026 13:32, Daniel P. Berrangé wrote:

> On Sun, Aug 23, 2026 at 11:07:18PM +0800, Yonggang Luo wrote:
> 
> snip,
> 
> ..to comment just on the end result for now..
> 
>> The last patch builds qemu-system (and qemu-systemw on Windows) from
>> aarch64 common/system objects plus RISC-V arch objects, and installs
>> qemu-system-{arm,aarch64,riscv32,riscv64} as symlinks so argv[0] still
>> selects TargetInfo.
>>
>> Examples:
>>
>>    qemu-system -target aarch64 -M virt ...
>>    qemu-system-riscv64 -M virt ...
>>
>> A basename that matches no registered token falls through to the unique
>> default. A combined binary with no suffix requires -target when more
>> than one default TargetInfo is registered.
> 
> In testing and comparing  the new qemu-system-riscv64 symlink
> to qemu-system vs the current standalone qemu-system-riscv64
> binary there are some significant user visible changes.
> 
> The simplest is 'qom-list-types' went from reporting approx
> 770 classes, to reporting approx 1530 classes. IOW, the
> qemu-system-riscv64 binary is now reporting supporting for
> all the classes that were unique to arm.
> 
> The '-device help' output similarly shows a great many more
> devices
> 
> TL;DR introspecting qemu-system-riscv64 is no longer accurate
> wrt riscv64 capabilities.
> 
> This is not suprising, since we register all TypeInfo meaning
> we get all QOM classes present. Some of Pierricks patches try
> to filter places which iterate over classes, but this does not
> have full coverage.
> 
> 
> I think this is probably also what leads to the increased RAM
> usage in qemu-system-riscv64. Starting
> 
>    qemu-system-riscv64 -nodefaults -display none -M none
> 
> shows an increase in RAM usage from  17.3 to 20.7 MB which
> is about 15% increase. NB this is dirty, private RAM per
> process. The shared RAM pages also increase but that's not
> a concern since they're common to all QEMU processes.
> 
> qemu-system-aarch64 shows a much smaller RAM increase, since
> it only grew from 1430 classes to 1530 classes.
> 
> We have many more target though, so if we assume the end
> point where every single target is unified, the the union
> of all classes for all targets comes to approx 3600.
> 
> My guesstimate is that would mean a memory increase for
> qemu-system-riscv64 from 17.3 to 39.9 MB, which is a
> 72% increase.
> 
> In absolute terms this is still modest, but for deployments
> with large VM counts  and small RAM sizes, that gets to be
> significant.
> 
> 
> None of this means single binary is a bad idea.
> 
> 
> My main takeaway is that we're creating uneccessary work
> for ourselves by trying to make 'qemu-sytem' identical
> in behaviour to qemu-system-$TARGET.
> 
> The complex filtering patches / QOM interfaces that I
> found uncomfortable in Pierrick's base series are largely
> around the filtering needed to simulate qemu-system-$TARGET,
> and they're still incomplete. I don't have high confidence
> in our ability to avoid regressions if we go route this
> route.
> 
> 
> IMHO we should make a clean break with the past. Leave
> the existing qemu-system-$TARGET binaries being built
> from the same pieces they are today, such that there
> is better confidence that we are not making behavioural
> changes to them.
> 
> 
> qemu-system should be built alongside qemu-system-$TARGET
> and offer new semantics where it is documented as exposing
> everything from all targets whenever introspected and does
> not apply target type or target Kconfig filtering to inputs/
> outputs.
> 
> We still get the benefit of only building most  .o files
> once, so keeping qemu-system-$TARGET is only a small
> overhead in the final step of linking everything together.
> 
> 
> qemu-system will still have the increased memory overhead
> but that's fine as qemu-system-$TARGET will be unaffected.
> We can tackle the memory overhead of qemu-system at our
> leisure through use of loadable modules, and thus not have
> that as a task to think about today.
> 
> 
> With the clean break with the past, we also have the
> ability to tackle various long standing design mistakes
> present in qemu-system-$TARGET instead of carrying them
> over into the new binary.
> 
> Specifically
> 
>   * -nodefaults should become the default
>   
>   * All CLI args should be processed in order from
>     the command line, so we eliminate the nonsense
>     where we process some -object, then -chardev,
>     then more -object through hand crafted deps
> 
>   * No default machine type

I would even go as far as to suggest that we should make modules 
mandatory for qemu-system, so that devices can be loaded upon demand 
during machine construction to help keep the size down.

I'll leave whether that is through dependency tracking or via an 
explicit load directive for someone else to decide :)
>   * Drop all legacy syntax so we only have a single
>     QAPI based way of configuring.
>     eg drop -hda, -hdb, -cdrom, -drive, etc
>        only keeping -blockdev
>     eg drop -mon, -monitor, -qmp, etc only
>        keeping -object

The only problem with this is that I often get a lot of complaints that 
QEMU command lines are complicated from retro folks who just want to run 
their favourite old games. Why would they want to come up with a 
long-winded -drive command line when they can just use -hda instead?

> We don't have to do all that straightaway. If we declare
> qemu-system "experimental" initially we can iterate on
> that intentionally breaking compat in releases, without
> any impact on qemu-system-$TARGET.
> 
> Avoiding the back compat task will give us more flexibility
> with the follow on work when people come to create new
> machine types with heterogenous CPU targets.
I agree that this is a good opportunity to explore new things without 
being tied to past decisions.


ATB,

Mark.



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-26 13:40   ` Mark Cave-Ayland
@ 2026-08-26 13:58     ` Daniel P. Berrangé
  2026-08-26 14:50     ` Yonggang Luo
  2026-08-26 20:41     ` Daniel Henrique Barboza
  2 siblings, 0 replies; 57+ messages in thread
From: Daniel P. Berrangé @ 2026-08-26 13:58 UTC (permalink / raw)
  To: Mark Cave-Ayland
  Cc: Yonggang Luo, qemu-devel, Xianglai Li, Alistair Francis,
	Chinmay Rath, Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu,
	Eric Farman, Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, Pierrick Bouvier, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Wed, Aug 26, 2026 at 02:40:46PM +0100, Mark Cave-Ayland wrote:
> On 26/08/2026 13:32, Daniel P. Berrangé wrote:
> 
> > On Sun, Aug 23, 2026 at 11:07:18PM +0800, Yonggang Luo wrote:
> > 
> > snip,
> > 
> > ..to comment just on the end result for now..
> > 
> > Specifically
> > 
> >   * -nodefaults should become the default
> >   * All CLI args should be processed in order from
> >     the command line, so we eliminate the nonsense
> >     where we process some -object, then -chardev,
> >     then more -object through hand crafted deps
> > 
> >   * No default machine type
> 
> I would even go as far as to suggest that we should make modules mandatory
> for qemu-system, so that devices can be loaded upon demand during machine
> construction to help keep the size down.

I think it is worth considering whether modules could be mandatory
unconditionally for everything. We don't need to block on this
decision though.

> I'll leave whether that is through dependency tracking or via an explicit
> load directive for someone else to decide :)
> >   * Drop all legacy syntax so we only have a single
> >     QAPI based way of configuring.
> >     eg drop -hda, -hdb, -cdrom, -drive, etc
> >        only keeping -blockdev
> >     eg drop -mon, -monitor, -qmp, etc only
> >        keeping -object
> 
> The only problem with this is that I often get a lot of complaints that QEMU
> command lines are complicated from retro folks who just want to run their
> favourite old games. Why would they want to come up with a long-winded
> -drive command line when they can just use -hda instead?

-blockdev isn't as hard as it appears - we make it harder than it ought
to be by not documenting it well and carrying on using -hda/-drive in
examples so users have little good guidance. Then when people go beyond
the needs that -hda can service, they have an worse experiance as a
result.

Having many different ways to do the same thing and not getting rid of
enough outdated/obsoleted stuff is what has always created confusion
for QEMU.

Also why it is -hda when it is created a SCSI disk (sda), or a VirtIO
disk (xda) or a SSD (mmcblk0), or the guest is calling it C:\ :-)

Yes, -hda is simple, but it is also nonsensical historical cruft.


All the various "convenience" args are also something that could be
provided by a higher level launcher script that translates to the
canonical syntax, even if they're not in qemu-system itself.

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] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-26 13:40   ` Mark Cave-Ayland
  2026-08-26 13:58     ` Daniel P. Berrangé
@ 2026-08-26 14:50     ` Yonggang Luo
  2026-08-26 20:41     ` Daniel Henrique Barboza
  2 siblings, 0 replies; 57+ messages in thread
From: Yonggang Luo @ 2026-08-26 14:50 UTC (permalink / raw)
  To: Mark Cave-Ayland
  Cc: Daniel P. Berrangé, qemu-devel, Xianglai Li,
	Alistair Francis, Chinmay Rath, Sunil V L, qemu-riscv,
	Alexander Bulekov, Zhao Liu, Eric Farman, Laurent Vivier,
	Peter Maydell, Chao Liu, Liu Zhiwei, Palmer Dabbelt, Song Gao,
	Harsh Prateek Bora, Glenn Miles, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

[-- Attachment #1: Type: text/plain, Size: 6764 bytes --]

On Wed, Aug 26, 2026 at 9:41 PM Mark Cave-Ayland <
mark.caveayland@nutanix.com> wrote:
>
> On 26/08/2026 13:32, Daniel P. Berrangé wrote:
>
> > On Sun, Aug 23, 2026 at 11:07:18PM +0800, Yonggang Luo wrote:
> >
> > snip,
> >
> > ..to comment just on the end result for now..
> >
> >> The last patch builds qemu-system (and qemu-systemw on Windows) from
> >> aarch64 common/system objects plus RISC-V arch objects, and installs
> >> qemu-system-{arm,aarch64,riscv32,riscv64} as symlinks so argv[0] still
> >> selects TargetInfo.
> >>
> >> Examples:
> >>
> >>    qemu-system -target aarch64 -M virt ...
> >>    qemu-system-riscv64 -M virt ...
> >>
> >> A basename that matches no registered token falls through to the unique
> >> default. A combined binary with no suffix requires -target when more
> >> than one default TargetInfo is registered.
> >
> > In testing and comparing  the new qemu-system-riscv64 symlink
> > to qemu-system vs the current standalone qemu-system-riscv64
> > binary there are some significant user visible changes.
> >
> > The simplest is 'qom-list-types' went from reporting approx
> > 770 classes, to reporting approx 1530 classes. IOW, the
> > qemu-system-riscv64 binary is now reporting supporting for
> > all the classes that were unique to arm.
> >
> > The '-device help' output similarly shows a great many more
> > devices
> >
> > TL;DR introspecting qemu-system-riscv64 is no longer accurate
> > wrt riscv64 capabilities.
> >
> > This is not suprising, since we register all TypeInfo meaning
> > we get all QOM classes present. Some of Pierricks patches try
> > to filter places which iterate over classes, but this does not
> > have full coverage.
> >
> >
> > I think this is probably also what leads to the increased RAM
> > usage in qemu-system-riscv64. Starting
> >
> >    qemu-system-riscv64 -nodefaults -display none -M none
> >
> > shows an increase in RAM usage from  17.3 to 20.7 MB which
> > is about 15% increase. NB this is dirty, private RAM per
> > process. The shared RAM pages also increase but that's not
> > a concern since they're common to all QEMU processes.
> >
> > qemu-system-aarch64 shows a much smaller RAM increase, since
> > it only grew from 1430 classes to 1530 classes.
> >
> > We have many more target though, so if we assume the end
> > point where every single target is unified, the the union
> > of all classes for all targets comes to approx 3600.
> >
> > My guesstimate is that would mean a memory increase for
> > qemu-system-riscv64 from 17.3 to 39.9 MB, which is a
> > 72% increase.
> >
> > In absolute terms this is still modest, but for deployments
> > with large VM counts  and small RAM sizes, that gets to be
> > significant.
> >
> >
> > None of this means single binary is a bad idea.
> >
> >
> > My main takeaway is that we're creating uneccessary work
> > for ourselves by trying to make 'qemu-sytem' identical
> > in behaviour to qemu-system-$TARGET.
> >
> > The complex filtering patches / QOM interfaces that I
> > found uncomfortable in Pierrick's base series are largely
> > around the filtering needed to simulate qemu-system-$TARGET,
> > and they're still incomplete. I don't have high confidence
> > in our ability to avoid regressions if we go route this
> > route.
> >
> >
> > IMHO we should make a clean break with the past. Leave
> > the existing qemu-system-$TARGET binaries being built
> > from the same pieces they are today, such that there
> > is better confidence that we are not making behavioural
> > changes to them.
> >
> >
> > qemu-system should be built alongside qemu-system-$TARGET
> > and offer new semantics where it is documented as exposing
> > everything from all targets whenever introspected and does
> > not apply target type or target Kconfig filtering to inputs/
> > outputs.
> >
> > We still get the benefit of only building most  .o files
> > once, so keeping qemu-system-$TARGET is only a small
> > overhead in the final step of linking everything together.
> >
> >
> > qemu-system will still have the increased memory overhead
> > but that's fine as qemu-system-$TARGET will be unaffected.
> > We can tackle the memory overhead of qemu-system at our
> > leisure through use of loadable modules, and thus not have
> > that as a task to think about today.
> >
> >
> > With the clean break with the past, we also have the
> > ability to tackle various long standing design mistakes
> > present in qemu-system-$TARGET instead of carrying them
> > over into the new binary.
> >
> > Specifically
> >
> >   * -nodefaults should become the default
> >
> >   * All CLI args should be processed in order from
> >     the command line, so we eliminate the nonsense
> >     where we process some -object, then -chardev,
> >     then more -object through hand crafted deps
> >
> >   * No default machine type
>
> I would even go as far as to suggest that we should make modules

This is also why I post these patches, i've already enabled better modules
support, so we can implement devices in dll(win32/linux/osx) all works.
I achieve that by introducing a new plugin and getting the memory to be
more configable. so that we can bind the device to dma-memory by option,
not by link.


> mandatory for qemu-system, so that devices can be loaded upon demand
> during machine construction to help keep the size down.
>
> I'll leave whether that is through dependency tracking or via an
> explicit load directive for someone else to decide :)
> >   * Drop all legacy syntax so we only have a single
> >     QAPI based way of configuring.
> >     eg drop -hda, -hdb, -cdrom, -drive, etc
> >        only keeping -blockdev
> >     eg drop -mon, -monitor, -qmp, etc only
> >        keeping -object
>
> The only problem with this is that I often get a lot of complaints that
> QEMU command lines are complicated from retro folks who just want to run
> their favourite old games. Why would they want to come up with a
> long-winded -drive command line when they can just use -hda instead?
>
> > We don't have to do all that straightaway. If we declare
> > qemu-system "experimental" initially we can iterate on
> > that intentionally breaking compat in releases, without
> > any impact on qemu-system-$TARGET.
> >
> > Avoiding the back compat task will give us more flexibility
> > with the follow on work when people come to create new
> > machine types with heterogenous CPU targets.
> I agree that this is a good opportunity to explore new things without
> being tied to past decisions.
>
>
> ATB,
>
> Mark.
>


--
         此致
礼
罗勇刚
Yours
    sincerely,
Yonggang Luo

[-- Attachment #2: Type: text/html, Size: 8280 bytes --]

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 12/12] meson: link ARM and RISC-V into qemu-system
  2026-08-26 13:00     ` Daniel P. Berrangé
@ 2026-08-26 17:40       ` Pierrick Bouvier
  2026-08-26 18:05         ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 57+ messages in thread
From: Pierrick Bouvier @ 2026-08-26 17:40 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Yonggang Luo, qemu-devel, Xianglai Li, Alistair Francis,
	Chinmay Rath, Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu,
	Eric Farman, Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 8/26/2026 6:00 AM, Daniel P. Berrangé wrote:
> On Mon, Aug 24, 2026 at 09:20:38AM -0700, Pierrick Bouvier wrote:
>> On 8/23/2026 8:07 AM, Yonggang Luo wrote:
>>> - Build qemu-system (and qemu-systemw on Windows) from aarch64
>>>   common/system objects plus RISC-V arch objects taken from the
>>>   existing riscv64 lib.
>>> - Pull 32-bit TargetInfo and 32-only boards from the arm/riscv32
>>>   libs so hw/arm and target/riscv are not compiled twice.
>>> - Skip linking qemu-system-{arm,aarch64,riscv32,riscv64} and the
>>>   Windows *w variants; symlink those names to qemu-system so
>>>   argv[0] still selects TargetInfo.
>>>
>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>>> ---
>>>  meson.build | 156 +++++++++++++++++++++++++++++++++++++++++++++++++---
>>>  1 file changed, 147 insertions(+), 9 deletions(-)
> 
> I think this approach of taking common/system from aarch64
> and adding in riscv specific objects only works by luck.
> 
> That's not obvious from your patch, but Pierrick's counterproposal
> below will expose it with a little  tweak....
> 
> 
>> From 6261b0c255e1a8f0df2b41928b8dfb365d0fa488 Mon Sep 17 00:00:00 2001
>> From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
>> Date: Tue, 14 Apr 2026 10:56:15 -0700
>> Subject: [PATCH] meson: build single binary
>>
>> This is not built by default.
>> Build with: ninja -C build qemu-system
>>
>> All available *-softmmu targets are aggregated, ./configure
>> --target-list can be used to restrict which targets are included.
>>
>> In case user has targets that are not supported, we emit an error
>> message when build qemu-system target. This way, it's not necessary to
>> have a custom configure flag, and qemu-system can live next to existing
>> binaries without complexifying the workflow more than it is already.
>>
>> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
>> ---
>>  meson.build | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 48 insertions(+)
>>
>> diff --git a/meson.build b/meson.build
>> index 553df3e7f053..4a31a520d9eb 100644
>> --- a/meson.build
>> +++ b/meson.build
>> @@ -4264,6 +4264,9 @@ if host_os == 'darwin'
>>  endif
>>  
>>  traceable = []
>> +single_binary_libs = []
>> +single_binary_deps = []
>> +single_binary_crates = []
>>  emulators = {}
>>  foreach target : target_dirs
>>    config_target = config_target_mak[target]
>> @@ -4419,6 +4422,10 @@ foreach target : target_dirs
>>                   build_by_default: false)
>>  
>>    if target.endswith('-softmmu')
>> +    single_binary_libs += lib
>> +    single_binary_deps += arch_deps
>> +    single_binary_deps += target_stubs
>> +    single_binary_crates += main_rs
>>      execs = [{
>>        'name': 'qemu-system-' + target_name,
>>        'win_subsystem': 'console',
>> @@ -4500,6 +4507,47 @@ foreach target : target_dirs
>>    endforeach
>>  endforeach
>>  
>> +single_binary_objects = []
>> +foreach lib: single_binary_libs
>> +  single_binary_objects += lib.extract_all_objects(recursive: true)
>> +endforeach
>> +
>> +single_binary_link_args = emulator_link_args
>> +single_binary_link_args += enable_modules ? ['@block.syms', '@qemu.syms'] : []
>> +
>> +supported_targets = [
>> +  'aarch64-softmmu',
>> +  'arm-softmmu',
>> +]
> 
> Adding in riscv64-softmmu to this list and building with
> configure --target-list=aarch64-softmmu,riscv64-softmmu
> will fail with this meson approach.
>

Maybe it's now more obvious why our original goal, presented at KVM
Forum 2025, was to have only arm/aarch64/microblaze, and not riscv.
It just requires more work to have it, and iteration is key. But we need
a minimum viable product to start somewhere.

It is still our goal to this date.

> Specifically we'll hit duplicate symbols to to taking
> different KConfig branches, resulting in building in
> both the real impl and the stubs:
> 
>   /usr/bin/ld.bfd: libsystem.a.p/hw_pci-bridge_pci_expander_bridge_stubs.c.o: in function `pxb_cxl_hook_up_registers':
> /home/berrange/src/virt/qemu/build-alt/../hw/pci-bridge/pci_expander_bridge_stubs.c:14: multiple definition of `pxb_cxl_hook_up_registers'; libsystem.a.p/hw_pci-bridge_pci_expander_bridge.c.o:/home/berrange/src/virt/qemu/build-alt/../hw/pci-bridge/pci_expander_bridge.c:214: first defined here
>

There is nothing new here, and we discovered all that more than a year
ago. That's why we started using stub_ss more, as it provides the weak
symbol semantic we need. It's not the end of the story though, as we'll
have to adapt some functions to this new "multi target" world.
But to be able to test and debug that, we need to have a single-binary
first.

> The problem is that aarch64 enables CONFIG_PXB and
> riscv64 does not.
> 
> Yonggang's patch only worked by luck since it preferred
> to the common system objects from aarch64 and thus kept
> the real PXB impl. If Yonggang had instead used common
> system objects from riscv64, the qemu-system would have
> lost the PXB impl and got a stub.
> 
> This is unfixable if both targets have some Kconfigs
> that the other target does not.
> 
> So to be able to build qemu-system, we can't simply
> pull in the union of objects from each architecture
> qemu-system-$TARGET binary. 
> 
> Instead we need to setup a new Kconfig specifically
> for qemu-system, which is the combination of all
> Kconfigs from each target. Then derive a new list
> of objects from that.  This shouldn't involve building
> any more .o files, just means we build an accurate
> list of what .o files we need.
>

It is a wrong analysis, and there is no need to have yet another
Kconfig. The only cases to handle to solve symbols duplication are:
- true conflict -> unify implementation or dispatch per target
- false conflict -> implementation vs stubs, solved with "weak symbols"
+ additional target/config checks on implementation.

The linker has the final word, and we just need to follow what it says.

>> +unsupported_targets = []
>> +foreach target : target_dirs
>> +  if target.endswith('-softmmu') and target not in supported_targets
>> +    unsupported_targets += target
>> +  endif
>> +endforeach
>> +
>> +if unsupported_targets.length() == 0
>> +  executable('qemu-system',
>> +             sources: [single_binary_crates, files('system/main.c')],
>> +             dependencies: single_binary_deps,
>> +             objects: single_binary_objects,
>> +             link_depends: [block_syms, qemu_syms],
>> +             link_args: single_binary_link_args,
>> +             build_by_default: false)
>> +else
>> +  error_str = f'''qemu-system only support targets:
>> +@supported_targets@
> 
> With the Kconfig union problem solved, IMHO we should unconditionally
> always build the 'qemu-system' binary. If there are targets that
> do not yet support the single bniary concept that's fine, just ignore
> them. qemu-system-$TARGET will still be built for everything, and
> qemu-system only needs to include what's currently possible.
>

No strong opinion here, I would be happy to implement a different
behavior for this. I personally prefer predictable/boring software
without any implicit behavior, and guide user to what it wants, instead
of guessing for him/her.

I didn't post this patch for review, just to show there is no need to
have a complex mechanic, and simply mixing object files together works,
once target was cleaned to work with single-binary.

This has been presented at KVM Forum 2025, and we didn't find any
situation that required to change our strategy so far.

> 
>> +
>> +unsupported targets:
>> +@unsupported_targets@
>> +
>> +use ./configure --target-list= to choose list of targets'''
>> +  t = custom_target(command: ['sh', '-c', 'echo "' + error_str + '" && exit 1'],
>> +                    output: 'none',
>> +                    build_by_default: false)
>> +  alias_target('qemu-system', t)
>> +endif
>> +
>>  # Other build targets
>>  
>>  if get_option('plugins')
> 
> 
> With regards,
> Daniel



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 12/12] meson: link ARM and RISC-V into qemu-system
  2026-08-26 17:40       ` Pierrick Bouvier
@ 2026-08-26 18:05         ` Philippe Mathieu-Daudé
  2026-08-26 18:08           ` Yonggang Luo
  0 siblings, 1 reply; 57+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-26 18:05 UTC (permalink / raw)
  To: Pierrick Bouvier, Daniel P. Berrangé
  Cc: Yonggang Luo, qemu-devel, Xianglai Li, Alistair Francis,
	Chinmay Rath, Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu,
	Eric Farman, Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 26/8/26 19:40, Pierrick Bouvier wrote:
> On 8/26/2026 6:00 AM, Daniel P. Berrangé wrote:
>> On Mon, Aug 24, 2026 at 09:20:38AM -0700, Pierrick Bouvier wrote:
>>> On 8/23/2026 8:07 AM, Yonggang Luo wrote:
>>>> - Build qemu-system (and qemu-systemw on Windows) from aarch64
>>>>    common/system objects plus RISC-V arch objects taken from the
>>>>    existing riscv64 lib.
>>>> - Pull 32-bit TargetInfo and 32-only boards from the arm/riscv32
>>>>    libs so hw/arm and target/riscv are not compiled twice.
>>>> - Skip linking qemu-system-{arm,aarch64,riscv32,riscv64} and the
>>>>    Windows *w variants; symlink those names to qemu-system so
>>>>    argv[0] still selects TargetInfo.
>>>>
>>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>>>> ---
>>>>   meson.build | 156 +++++++++++++++++++++++++++++++++++++++++++++++++---
>>>>   1 file changed, 147 insertions(+), 9 deletions(-)
>>
>> I think this approach of taking common/system from aarch64
>> and adding in riscv specific objects only works by luck.
>>
>> That's not obvious from your patch, but Pierrick's counterproposal
>> below will expose it with a little  tweak....
>>
>>
>>>  From 6261b0c255e1a8f0df2b41928b8dfb365d0fa488 Mon Sep 17 00:00:00 2001
>>> From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
>>> Date: Tue, 14 Apr 2026 10:56:15 -0700
>>> Subject: [PATCH] meson: build single binary
>>>
>>> This is not built by default.
>>> Build with: ninja -C build qemu-system
>>>
>>> All available *-softmmu targets are aggregated, ./configure
>>> --target-list can be used to restrict which targets are included.
>>>
>>> In case user has targets that are not supported, we emit an error
>>> message when build qemu-system target. This way, it's not necessary to
>>> have a custom configure flag, and qemu-system can live next to existing
>>> binaries without complexifying the workflow more than it is already.
>>>
>>> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
>>> ---
>>>   meson.build | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>   1 file changed, 48 insertions(+)
>>>
>>> diff --git a/meson.build b/meson.build
>>> index 553df3e7f053..4a31a520d9eb 100644
>>> --- a/meson.build
>>> +++ b/meson.build
>>> @@ -4264,6 +4264,9 @@ if host_os == 'darwin'
>>>   endif
>>>   
>>>   traceable = []
>>> +single_binary_libs = []
>>> +single_binary_deps = []
>>> +single_binary_crates = []
>>>   emulators = {}
>>>   foreach target : target_dirs
>>>     config_target = config_target_mak[target]
>>> @@ -4419,6 +4422,10 @@ foreach target : target_dirs
>>>                    build_by_default: false)
>>>   
>>>     if target.endswith('-softmmu')
>>> +    single_binary_libs += lib
>>> +    single_binary_deps += arch_deps
>>> +    single_binary_deps += target_stubs
>>> +    single_binary_crates += main_rs
>>>       execs = [{
>>>         'name': 'qemu-system-' + target_name,
>>>         'win_subsystem': 'console',
>>> @@ -4500,6 +4507,47 @@ foreach target : target_dirs
>>>     endforeach
>>>   endforeach
>>>   
>>> +single_binary_objects = []
>>> +foreach lib: single_binary_libs
>>> +  single_binary_objects += lib.extract_all_objects(recursive: true)
>>> +endforeach
>>> +
>>> +single_binary_link_args = emulator_link_args
>>> +single_binary_link_args += enable_modules ? ['@block.syms', '@qemu.syms'] : []
>>> +
>>> +supported_targets = [
>>> +  'aarch64-softmmu',
>>> +  'arm-softmmu',
>>> +]
>>
>> Adding in riscv64-softmmu to this list and building with
>> configure --target-list=aarch64-softmmu,riscv64-softmmu
>> will fail with this meson approach.
>>
> 
> Maybe it's now more obvious why our original goal, presented at KVM
> Forum 2025, was to have only arm/aarch64/microblaze, and not riscv.
> It just requires more work to have it, and iteration is key. But we need
> a minimum viable product to start somewhere.
> 
> It is still our goal to this date.
> 
>> Specifically we'll hit duplicate symbols to to taking
>> different KConfig branches, resulting in building in
>> both the real impl and the stubs:
>>
>>    /usr/bin/ld.bfd: libsystem.a.p/hw_pci-bridge_pci_expander_bridge_stubs.c.o: in function `pxb_cxl_hook_up_registers':
>> /home/berrange/src/virt/qemu/build-alt/../hw/pci-bridge/pci_expander_bridge_stubs.c:14: multiple definition of `pxb_cxl_hook_up_registers'; libsystem.a.p/hw_pci-bridge_pci_expander_bridge.c.o:/home/berrange/src/virt/qemu/build-alt/../hw/pci-bridge/pci_expander_bridge.c:214: first defined here
>>
> 
> There is nothing new here, and we discovered all that more than a year
> ago. That's why we started using stub_ss more, as it provides the weak
> symbol semantic we need. It's not the end of the story though, as we'll
> have to adapt some functions to this new "multi target" world.
> But to be able to test and debug that, we need to have a single-binary
> first.

I will try to find time to finish that 'HOWTO convert to single-binary'
document I proposed to Daniel Barboza and Anton Johansson which is
structured as "why / how / commit references", that could help Yonggang
and others to understand why this effort is taking so long.


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 12/12] meson: link ARM and RISC-V into qemu-system
  2026-08-26 18:05         ` Philippe Mathieu-Daudé
@ 2026-08-26 18:08           ` Yonggang Luo
  0 siblings, 0 replies; 57+ messages in thread
From: Yonggang Luo @ 2026-08-26 18:08 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: Pierrick Bouvier, Daniel P. Berrangé, qemu-devel,
	Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

[-- Attachment #1: Type: text/plain, Size: 5781 bytes --]

I took some ideas from you and improved it to be smaller. I'll send a v2
patches I think it's better, your review concerns are all addressed.

On Thu, Aug 27, 2026 at 2:05 AM Philippe Mathieu-Daudé <
philmd@oss.qualcomm.com> wrote:
>
> On 26/8/26 19:40, Pierrick Bouvier wrote:
> > On 8/26/2026 6:00 AM, Daniel P. Berrangé wrote:
> >> On Mon, Aug 24, 2026 at 09:20:38AM -0700, Pierrick Bouvier wrote:
> >>> On 8/23/2026 8:07 AM, Yonggang Luo wrote:
> >>>> - Build qemu-system (and qemu-systemw on Windows) from aarch64
> >>>>    common/system objects plus RISC-V arch objects taken from the
> >>>>    existing riscv64 lib.
> >>>> - Pull 32-bit TargetInfo and 32-only boards from the arm/riscv32
> >>>>    libs so hw/arm and target/riscv are not compiled twice.
> >>>> - Skip linking qemu-system-{arm,aarch64,riscv32,riscv64} and the
> >>>>    Windows *w variants; symlink those names to qemu-system so
> >>>>    argv[0] still selects TargetInfo.
> >>>>
> >>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> >>>> ---
> >>>>   meson.build | 156
+++++++++++++++++++++++++++++++++++++++++++++++++---
> >>>>   1 file changed, 147 insertions(+), 9 deletions(-)
> >>
> >> I think this approach of taking common/system from aarch64
> >> and adding in riscv specific objects only works by luck.
> >>
> >> That's not obvious from your patch, but Pierrick's counterproposal
> >> below will expose it with a little  tweak....
> >>
> >>
> >>>  From 6261b0c255e1a8f0df2b41928b8dfb365d0fa488 Mon Sep 17 00:00:00
2001
> >>> From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
> >>> Date: Tue, 14 Apr 2026 10:56:15 -0700
> >>> Subject: [PATCH] meson: build single binary
> >>>
> >>> This is not built by default.
> >>> Build with: ninja -C build qemu-system
> >>>
> >>> All available *-softmmu targets are aggregated, ./configure
> >>> --target-list can be used to restrict which targets are included.
> >>>
> >>> In case user has targets that are not supported, we emit an error
> >>> message when build qemu-system target. This way, it's not necessary to
> >>> have a custom configure flag, and qemu-system can live next to
existing
> >>> binaries without complexifying the workflow more than it is already.
> >>>
> >>> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
> >>> ---
> >>>   meson.build | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
> >>>   1 file changed, 48 insertions(+)
> >>>
> >>> diff --git a/meson.build b/meson.build
> >>> index 553df3e7f053..4a31a520d9eb 100644
> >>> --- a/meson.build
> >>> +++ b/meson.build
> >>> @@ -4264,6 +4264,9 @@ if host_os == 'darwin'
> >>>   endif
> >>>
> >>>   traceable = []
> >>> +single_binary_libs = []
> >>> +single_binary_deps = []
> >>> +single_binary_crates = []
> >>>   emulators = {}
> >>>   foreach target : target_dirs
> >>>     config_target = config_target_mak[target]
> >>> @@ -4419,6 +4422,10 @@ foreach target : target_dirs
> >>>                    build_by_default: false)
> >>>
> >>>     if target.endswith('-softmmu')
> >>> +    single_binary_libs += lib
> >>> +    single_binary_deps += arch_deps
> >>> +    single_binary_deps += target_stubs
> >>> +    single_binary_crates += main_rs
> >>>       execs = [{
> >>>         'name': 'qemu-system-' + target_name,
> >>>         'win_subsystem': 'console',
> >>> @@ -4500,6 +4507,47 @@ foreach target : target_dirs
> >>>     endforeach
> >>>   endforeach
> >>>
> >>> +single_binary_objects = []
> >>> +foreach lib: single_binary_libs
> >>> +  single_binary_objects += lib.extract_all_objects(recursive: true)
> >>> +endforeach
> >>> +
> >>> +single_binary_link_args = emulator_link_args
> >>> +single_binary_link_args += enable_modules ? ['@block.syms',
'@qemu.syms'] : []
> >>> +
> >>> +supported_targets = [
> >>> +  'aarch64-softmmu',
> >>> +  'arm-softmmu',
> >>> +]
> >>
> >> Adding in riscv64-softmmu to this list and building with
> >> configure --target-list=aarch64-softmmu,riscv64-softmmu
> >> will fail with this meson approach.
> >>
> >
> > Maybe it's now more obvious why our original goal, presented at KVM
> > Forum 2025, was to have only arm/aarch64/microblaze, and not riscv.
> > It just requires more work to have it, and iteration is key. But we need
> > a minimum viable product to start somewhere.
> >
> > It is still our goal to this date.
> >
> >> Specifically we'll hit duplicate symbols to to taking
> >> different KConfig branches, resulting in building in
> >> both the real impl and the stubs:
> >>
> >>    /usr/bin/ld.bfd:
libsystem.a.p/hw_pci-bridge_pci_expander_bridge_stubs.c.o: in function
`pxb_cxl_hook_up_registers':
> >>
/home/berrange/src/virt/qemu/build-alt/../hw/pci-bridge/pci_expander_bridge_stubs.c:14:
multiple definition of `pxb_cxl_hook_up_registers';
libsystem.a.p/hw_pci-bridge_pci_expander_bridge.c.o:/home/berrange/src/virt/qemu/build-alt/../hw/pci-bridge/pci_expander_bridge.c:214:
first defined here
> >>
> >
> > There is nothing new here, and we discovered all that more than a year
> > ago. That's why we started using stub_ss more, as it provides the weak
> > symbol semantic we need. It's not the end of the story though, as we'll
> > have to adapt some functions to this new "multi target" world.
> > But to be able to test and debug that, we need to have a single-binary
> > first.
>
> I will try to find time to finish that 'HOWTO convert to single-binary'
> document I proposed to Daniel Barboza and Anton Johansson which is
> structured as "why / how / commit references", that could help Yonggang
> and others to understand why this effort is taking so long.



--
         此致
礼
罗勇刚
Yours
    sincerely,
Yonggang Luo

[-- Attachment #2: Type: text/html, Size: 7768 bytes --]

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 10/12] target-info: add -target and program-name selection
  2026-08-26 12:46   ` Daniel P. Berrangé
@ 2026-08-26 18:13     ` Pierrick Bouvier
  2026-08-27 10:13       ` Daniel P. Berrangé
  2026-08-27 12:25     ` Daniel P. Berrangé
  1 sibling, 1 reply; 57+ messages in thread
From: Pierrick Bouvier @ 2026-08-26 18:13 UTC (permalink / raw)
  To: Daniel P. Berrangé, Yonggang Luo
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 8/26/2026 5:46 AM, Daniel P. Berrangé wrote:
> On Sun, Aug 23, 2026 at 11:07:28PM +0800, Yonggang Luo wrote:
>> - Parse -target before TargetInfo is fixed; CLI overrides the program
>>   basename.
>> - Tokens are target_name or target_name-be / -le; -target help lists
>>   registered names in sorted order.
>> - When -target is omitted, infer the token from g_get_prgname(): strip
>>   .exe, take the longest dash-separated registered suffix, and retry
>>   without a trailing w for Windows GUI binaries.
>> - A basename that matches no registered token falls through to the
>>   unique default. Combined binaries with no suffix require -target
>>   when more than one default TargetInfo is registered.
> 
> IMHO this -target argument and the target interference from
> program name is a mistaken direction.  We're being led off
> course by the attempt to make the new qemu-system be identical
> to qemu-system-$TARGET.
>

Heterogeneous emulation has been discussed for a very long time in the
community. The main breakthrough that we (precisely Philippe and I) made
in 2025 was to offer a simple path towards it. The approach is as simple
as "let's put the code together and make sure it links", and it worked
incredibly well, bringing our attention to all the details we needed to
take care of one after another. No more, no less.

By implementing *strict* identical behavior with existing binaries, we
indeed didn't add any new feature, but:
- we reduced total number of compilation units by 30%
- we cleaned up a lot of headers and did a lot of refactoring
- we have a systematic approach to add new targets in single-binary
while being able to reuse all existing tests without any change.

From my point of view, what you see as a detour was precisely what made
us progress so far in a year.

> If we ignore historical compat and treat qemu-system as a
> clean break, then I'd suggest that 'target' is not a concept
> to be exposed to the user at all.
>

If your only problem is with having a new -target option, I would be
happy to just keep the behavior to derive the target from current binary
name. That's a very small compromise on my side, and -target is just
here for convenience. It's not the end of the path.

> The user cares about the machine (and CPUs) they want to run,
> and their choice in this respect is what should determine the
> target(s) QEMU needs to enable. We should take
> 
>   qemu-system --machine vexpress-a15
> 
> that tells us we need the arm target. If we need to distinguish
> arm7 vs aarch64, then the choice of -cpu should determine 32
> bs 64 bit.
> 
> This extends better into the future world where we have
> machine type that could involve CPUs from multiple targets.
> 
> IOW machine config option / QOM class is what we should pivot
> off rather than a global target config option.
> 
> This likely implies that the MachineClass should gain a class
> method to query the QEMU_ARCH_XXXX bitmask required. Initially
> restricted to only a single target, so you can wire that through
> to the current global target info at startup. Later expanded to
> support multiple concurrent targets.
>

While it sounds nice on paper, you will be doomed to ambiguity with this:

qemu-system -machine virt -cpu max

What is your next plan? add an environment variable to solve it?
Name aliases that require us to use gdb or -d qom_debug to know what is
really instantiated?

Deriving target from argv(0) or -target is explicit, predictable, boring
and reliable, and it's exactly what we need now.

There are other paths for heterogeneous, and I would ask you some
patience, so we can talk about it at/after KVM Forum 2026, where I'll
present a talk about Heterogeneous emulation and some of our exploratory
ideas on how to run this.

Meanwhile, let's all focus on having a boring/predictable single-binary
please, and then we can all have fun reinventing the wheel.

> With regards,
> Daniel

Regards,
Pierrick


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-26 12:32 ` Daniel P. Berrangé
  2026-08-26 13:40   ` Mark Cave-Ayland
@ 2026-08-26 18:35   ` Pierrick Bouvier
  2026-08-26 18:53     ` Pierrick Bouvier
                       ` (2 more replies)
  2026-08-27 17:59   ` Paolo Bonzini
  2 siblings, 3 replies; 57+ messages in thread
From: Pierrick Bouvier @ 2026-08-26 18:35 UTC (permalink / raw)
  To: Daniel P. Berrangé, Yonggang Luo
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 8/26/2026 5:32 AM, Daniel P. Berrangé wrote:
> On Sun, Aug 23, 2026 at 11:07:18PM +0800, Yonggang Luo wrote:
> 
> snip,
> 
> ..to comment just on the end result for now..
> 
>> The last patch builds qemu-system (and qemu-systemw on Windows) from
>> aarch64 common/system objects plus RISC-V arch objects, and installs
>> qemu-system-{arm,aarch64,riscv32,riscv64} as symlinks so argv[0] still
>> selects TargetInfo.
>>
>> Examples:
>>
>>   qemu-system -target aarch64 -M virt ...
>>   qemu-system-riscv64 -M virt ...
>>
>> A basename that matches no registered token falls through to the unique
>> default. A combined binary with no suffix requires -target when more
>> than one default TargetInfo is registered.
> 
> In testing and comparing  the new qemu-system-riscv64 symlink
> to qemu-system vs the current standalone qemu-system-riscv64
> binary there are some significant user visible changes.
> 
> The simplest is 'qom-list-types' went from reporting approx
> 770 classes, to reporting approx 1530 classes. IOW, the
> qemu-system-riscv64 binary is now reporting supporting for
> all the classes that were unique to arm.
> 
> The '-device help' output similarly shows a great many more
> devices
> 
> TL;DR introspecting qemu-system-riscv64 is no longer accurate
> wrt riscv64 capabilities. 
> 
> This is not suprising, since we register all TypeInfo meaning
> we get all QOM classes present. Some of Pierricks patches try
> to filter places which iterate over classes, but this does not
> have full coverage.
>

I would add that if you would focus on reviewing and helping for this
filter problem instead of reinventing the wheel for command line, it
would be solved by now.

> 
> I think this is probably also what leads to the increased RAM
> usage in qemu-system-riscv64. Starting
> 
>   qemu-system-riscv64 -nodefaults -display none -M none
> 
> shows an increase in RAM usage from  17.3 to 20.7 MB which
> is about 15% increase. NB this is dirty, private RAM per
> process. The shared RAM pages also increase but that's not
> a concern since they're common to all QEMU processes.
> 
> qemu-system-aarch64 shows a much smaller RAM increase, since
> it only grew from 1430 classes to 1530 classes.
> 
> We have many more target though, so if we assume the end
> point where every single target is unified, the the union
> of all classes for all targets comes to approx 3600.
> 
> My guesstimate is that would mean a memory increase for
> qemu-system-riscv64 from 17.3 to 39.9 MB, which is a
> 72% increase.
> 
> In absolute terms this is still modest, but for deployments
> with large VM counts  and small RAM sizes, that gets to be
> significant.
>

How surprising (:eye-roll:) it is that adding more code and more classes
would result in a higher memory usage, or bigger binary size for
qemu-system.

More seriously. If someone is concerned about it, the simple solution is
to restrict list of targets and/or Kconfig to include less.

> 
> None of this means single binary is a bad idea.
> 
> 
> My main takeaway is that we're creating uneccessary work
> for ourselves by trying to make 'qemu-sytem' identical
> in behaviour to qemu-system-$TARGET.
> 
> The complex filtering patches / QOM interfaces that I
> found uncomfortable in Pierrick's base series are largely
> around the filtering needed to simulate qemu-system-$TARGET,
> and they're still incomplete. I don't have high confidence
> in our ability to avoid regressions if we go route this
> route.
> 
> 
> IMHO we should make a clean break with the past. Leave
> the existing qemu-system-$TARGET binaries being built
> from the same pieces they are today, such that there
> is better confidence that we are not making behavioural
> changes to them.
>

Funny enough, it reminded me word for word of a blog post from a
Microsoft employee where he explained that powershell existed only
because young developers were scared to modify original cmd shell.

Regression issues are solved with testing and good design, not by
inventing new things.

> 
> qemu-system should be built alongside qemu-system-$TARGET
> and offer new semantics where it is documented as exposing
> everything from all targets whenever introspected and does
> not apply target type or target Kconfig filtering to inputs/
> outputs. 
> 
> We still get the benefit of only building most  .o files
> once, so keeping qemu-system-$TARGET is only a small
> overhead in the final step of linking everything together.
> 
> 
> qemu-system will still have the increased memory overhead
> but that's fine as qemu-system-$TARGET will be unaffected.
> We can tackle the memory overhead of qemu-system at our
> leisure through use of loadable modules, and thus not have
> that as a task to think about today.
> 
> 
> With the clean break with the past, we also have the
> ability to tackle various long standing design mistakes
> present in qemu-system-$TARGET instead of carrying them
> over into the new binary.
> 
> Specifically
> 
>  * -nodefaults should become the default
>  
>  * All CLI args should be processed in order from
>    the command line, so we eliminate the nonsense
>    where we process some -object, then -chardev,
>    then more -object through hand crafted deps
> 
>  * No default machine type
> 
>  * Drop all legacy syntax so we only have a single
>    QAPI based way of configuring.
>    eg drop -hda, -hdb, -cdrom, -drive, etc
>       only keeping -blockdev
>    eg drop -mon, -monitor, -qmp, etc only
>       keeping -object
> 
> We don't have to do all that straightaway. If we declare
> qemu-system "experimental" initially we can iterate on
> that intentionally breaking compat in releases, without
> any impact on qemu-system-$TARGET.
> 
> Avoiding the back compat task will give us more flexibility
> with the follow on work when people come to create new
> machine types with heterogenous CPU targets.
>

Seems like the Genius.Artist. in the bottle just need to escape, and you
can send us a nice series doing all this. Meanwhile, I'll try to find a
carpet, a monkey, a princess and a suit to be the next Aladdin.

> 
> With regards,
> Daniel

Regards,
Pierrick


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 08/12] target/riscv: seed cfg.big_endian from TargetInfo
  2026-08-23 15:07 ` [PATCH 08/12] target/riscv: seed cfg.big_endian from TargetInfo Yonggang Luo
@ 2026-08-26 18:37   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 57+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-26 18:37 UTC (permalink / raw)
  To: Yonggang Luo, qemu-devel
  Cc: Xianglai Li, Alistair Francis, Chinmay Rath, Sunil V L,
	qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 23/8/26 17:07, Yonggang Luo wrote:
> GDB register packets use target_big_endian() only (gdb_get_reg16/32/64).
> RISC-V gdbstub already goes through those helpers, so future GDB
> big-endian support does not need a second endian source in the CPU
> gdbstub. It needs TargetInfo and the hart to agree.
> 
> Hart endian is cpu->cfg.big_endian, copied into mstatus MBE/SBE/UBE at
> reset. The CPU property still defaults to little-endian, so a
> big-endian TargetInfo would make GDB swap as BE while the hart stayed
> LE.
> 
> - Initialize cfg.big_endian from target_big_endian() in cpu init so a
>    big-endian TargetInfo also sets the hart.
> - Fail realize when -cpu big-endian= disagrees with that selection.
>    GDB cannot follow a per-CPU override, so a split would silently
>    corrupt register byte order.
> 
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>   target/riscv/cpu.c | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 5a82e6563bf..0681bec0bef 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -29,6 +29,7 @@
>   #include "qapi/error.h"
>   #include "qapi/visitor.h"
>   #include "qemu/error-report.h"
> +#include "qemu/target-info.h"
>   #include "qemu/timer.h"
>   #include "hw/core/qdev-properties.h"
>   #include "hw/core/qdev-prop-internal.h"
> @@ -1226,6 +1227,13 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>       RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
>       Error *local_err = NULL;
>   
> +    if (cpu->cfg.big_endian != target_big_endian()) {
> +        error_setg(errp,
> +                   "CPU big-endian=%s does not match selected target endian",
> +                   cpu->cfg.big_endian ? "on" : "off");

Surely the bug is on the GDB path.
> +        return;
> +    }
> +
>       cpu_exec_realizefn(cs, &local_err);
>       if (local_err != NULL) {
>           error_propagate(errp, local_err);


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 09/12] target-info: register le and be TargetInfo variants
  2026-08-24 19:01     ` Yonggang Luo
@ 2026-08-26 18:41       ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 57+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-26 18:41 UTC (permalink / raw)
  To: luoyonggang, Pierrick Bouvier
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel P. Berrangé, Daniel Henrique Barboza, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 24/8/26 21:01, Yonggang Luo wrote:
> On Tue, Aug 25, 2026 at 12:22 AM Pierrick Bouvier <
> pierrick.bouvier@oss.qualcomm.com> wrote:
>>
>> On 8/23/2026 8:07 AM, Yonggang Luo wrote:
>>> - Register target-info-<name>-le and -be from one system
>>>    target-info-def.c unit, sharing arch fields.
>>> - Mark is_default from TARGET_BIG_ENDIAN so riscv/arm stay LE and
>>>    ppc/s390x stay BE when -target is omitted.
>>> - Pick the unique default in target_info_qom_set_target() when more
>>>    than one TargetInfo is registered. Leave user-mode as a single
>>>    target_info().
>>>
>>> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
>>> ---
>>>   include/qemu/target-info-impl.h |  6 ++++
>>>   include/qemu/target-info-init.h | 29 +++++++++++++---
>>>   target-info-def.c               | 61 +++++++++++++++++++++++++--------
>>>   target-info-qom.c               | 33 ++++++++++++++----
>>>   4 files changed, 104 insertions(+), 25 deletions(-)

Clearly not the path we choose, have a look for example at how
we converted MicroBlaze:

$ git log --oneline */microblaze/ | fgrep -i endian
41c417290df target/microblaze: Fix endianness used to disassemble
1346a811234 hw/microblaze: Replace TARGET_BIG_ENDIAN -> target_big_endian()
9281c68deca target/microblaze: Directly check endianness via 
CPUConfig::endi flag
91fc6d8101d linux-user/microblaze: Fix little-endianness binary
0e259fa5a13 hw/microblaze: Remove the big-endian variants of ml605 and 
xlnx-zynqmp-pmu
141ec228deb hw/microblaze: Add endianness property to the 
petalogix_s3adsp1800 machine
eb3020b6ed2 hw/microblaze: Evaluate TARGET_BIG_ENDIAN at compile time
840e0862c52 target/microblaze: Set disassemble_info::endian value in 
disas_set_info
415aae543ed target/microblaze: Consider endianness while translating code
2c9e8ddd769 target/microblaze: Introduce mo_endian() helper
e87c93df113 hw/ssi/xilinx_spi: Make device endianness configurable
8a8c92c8afb hw/char/xilinx_uartlite: Make device endianness configurable
df1f35ab67e hw/timer/xilinx_timer: Make device endianness configurable
644276db5d7 hw/net/xilinx_ethlite: Make device endianness configurable
2cdf693b197 hw/intc/xilinx_intc: Make device endianness configurable
adc1a4a26a9 hw/loader: Pass ELFDATA endian order argument to load_elf()
8f27e70e3bc hw/microblaze: Propagate CPU endianness to 
microblaze_load_kernel()
c36ec3a9655 hw/microblaze/s3adsp1800: Explicit CPU endianness
181b3a7bb03 hw/microblaze: Deprecate big-endian petalogix-ml605 & 
xlnx-zynqmp-pmu
6c8cec822f1 target/microblaze: Alias CPU endianness property as 
'little-endian'

>> Is it representing existing targets, or adding new ones per endianness?
>> I'm not sure if the goal is to add new binaries, or mimic existing ones
>> with specific parameters.
> 
> 
> Is optional now, not a force requirement, this is needed when we use GDB
> debug qemu riscv-be, as gdbstub are depends on target_info

Again the bug you want to fix is on the gdbstub path.


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-26 18:35   ` Pierrick Bouvier
@ 2026-08-26 18:53     ` Pierrick Bouvier
  2026-08-27  9:44     ` Daniel P. Berrangé
  2026-08-27 10:22     ` Daniel P. Berrangé
  2 siblings, 0 replies; 57+ messages in thread
From: Pierrick Bouvier @ 2026-08-26 18:53 UTC (permalink / raw)
  To: Daniel P. Berrangé, Yonggang Luo
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 8/26/2026 11:35 AM, Pierrick Bouvier wrote:
> On 8/26/2026 5:32 AM, Daniel P. Berrangé wrote:
>> On Sun, Aug 23, 2026 at 11:07:18PM +0800, Yonggang Luo wrote:
>>
>> snip,
>>
>> ..to comment just on the end result for now..
>>
>>> The last patch builds qemu-system (and qemu-systemw on Windows) from
>>> aarch64 common/system objects plus RISC-V arch objects, and installs
>>> qemu-system-{arm,aarch64,riscv32,riscv64} as symlinks so argv[0] still
>>> selects TargetInfo.
>>>
>>> Examples:
>>>
>>>   qemu-system -target aarch64 -M virt ...
>>>   qemu-system-riscv64 -M virt ...
>>>
>>> A basename that matches no registered token falls through to the unique
>>> default. A combined binary with no suffix requires -target when more
>>> than one default TargetInfo is registered.
>>
>> In testing and comparing  the new qemu-system-riscv64 symlink
>> to qemu-system vs the current standalone qemu-system-riscv64
>> binary there are some significant user visible changes.
>>
>> The simplest is 'qom-list-types' went from reporting approx
>> 770 classes, to reporting approx 1530 classes. IOW, the
>> qemu-system-riscv64 binary is now reporting supporting for
>> all the classes that were unique to arm.
>>
>> The '-device help' output similarly shows a great many more
>> devices
>>
>> TL;DR introspecting qemu-system-riscv64 is no longer accurate
>> wrt riscv64 capabilities. 
>>
>> This is not suprising, since we register all TypeInfo meaning
>> we get all QOM classes present. Some of Pierricks patches try
>> to filter places which iterate over classes, but this does not
>> have full coverage.
>>
> 
> I would add that if you would focus on reviewing and helping for this
> filter problem instead of reinventing the wheel for command line, it
> would be solved by now.
> 
>>
>> I think this is probably also what leads to the increased RAM
>> usage in qemu-system-riscv64. Starting
>>
>>   qemu-system-riscv64 -nodefaults -display none -M none
>>
>> shows an increase in RAM usage from  17.3 to 20.7 MB which
>> is about 15% increase. NB this is dirty, private RAM per
>> process. The shared RAM pages also increase but that's not
>> a concern since they're common to all QEMU processes.
>>
>> qemu-system-aarch64 shows a much smaller RAM increase, since
>> it only grew from 1430 classes to 1530 classes.
>>
>> We have many more target though, so if we assume the end
>> point where every single target is unified, the the union
>> of all classes for all targets comes to approx 3600.
>>
>> My guesstimate is that would mean a memory increase for
>> qemu-system-riscv64 from 17.3 to 39.9 MB, which is a
>> 72% increase.
>>
>> In absolute terms this is still modest, but for deployments
>> with large VM counts  and small RAM sizes, that gets to be
>> significant.
>>
> 
> How surprising (:eye-roll:) it is that adding more code and more classes
> would result in a higher memory usage, or bigger binary size for
> qemu-system.
> 
> More seriously. If someone is concerned about it, the simple solution is
> to restrict list of targets and/or Kconfig to include less.
> 
>>
>> None of this means single binary is a bad idea.
>>
>>
>> My main takeaway is that we're creating uneccessary work
>> for ourselves by trying to make 'qemu-sytem' identical
>> in behaviour to qemu-system-$TARGET.
>>
>> The complex filtering patches / QOM interfaces that I
>> found uncomfortable in Pierrick's base series are largely
>> around the filtering needed to simulate qemu-system-$TARGET,
>> and they're still incomplete. I don't have high confidence
>> in our ability to avoid regressions if we go route this
>> route.
>>
>>
>> IMHO we should make a clean break with the past. Leave
>> the existing qemu-system-$TARGET binaries being built
>> from the same pieces they are today, such that there
>> is better confidence that we are not making behavioural
>> changes to them.
>>
> 
> Funny enough, it reminded me word for word of a blog post from a
> Microsoft employee where he explained that powershell existed only
> because young developers were scared to modify original cmd shell.
> 
> Regression issues are solved with testing and good design, not by
> inventing new things.
> 
>>
>> qemu-system should be built alongside qemu-system-$TARGET
>> and offer new semantics where it is documented as exposing
>> everything from all targets whenever introspected and does
>> not apply target type or target Kconfig filtering to inputs/
>> outputs. 
>>
>> We still get the benefit of only building most  .o files
>> once, so keeping qemu-system-$TARGET is only a small
>> overhead in the final step of linking everything together.
>>
>>
>> qemu-system will still have the increased memory overhead
>> but that's fine as qemu-system-$TARGET will be unaffected.
>> We can tackle the memory overhead of qemu-system at our
>> leisure through use of loadable modules, and thus not have
>> that as a task to think about today.
>>
>>
>> With the clean break with the past, we also have the
>> ability to tackle various long standing design mistakes
>> present in qemu-system-$TARGET instead of carrying them
>> over into the new binary.
>>
>> Specifically
>>
>>  * -nodefaults should become the default
>>  
>>  * All CLI args should be processed in order from
>>    the command line, so we eliminate the nonsense
>>    where we process some -object, then -chardev,
>>    then more -object through hand crafted deps
>>
>>  * No default machine type
>>
>>  * Drop all legacy syntax so we only have a single
>>    QAPI based way of configuring.
>>    eg drop -hda, -hdb, -cdrom, -drive, etc
>>       only keeping -blockdev
>>    eg drop -mon, -monitor, -qmp, etc only
>>       keeping -object
>>
>> We don't have to do all that straightaway. If we declare
>> qemu-system "experimental" initially we can iterate on
>> that intentionally breaking compat in releases, without
>> any impact on qemu-system-$TARGET.
>>
>> Avoiding the back compat task will give us more flexibility
>> with the follow on work when people come to create new
>> machine types with heterogenous CPU targets.
>>
> 
> Seems like the Genius.Artist. in the bottle just need to escape, and you
> can send us a nice series doing all this. Meanwhile, I'll try to find a
> carpet, a monkey, a princess and a suit to be the next Aladdin.
>

I was wondering why my brain connected with this, but watching "A whole
new world" video clip and lyrics made it obvious.
https://www.youtube.com/watch?v=EXTLJmYsaUQ&list=RDEXTLJmYsaUQ&start_radio=1

Now, we definitely need an AI generated version for heterogeneous
emulation :)

>>
>> With regards,
>> Daniel
> 
> Regards,
> Pierrick



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-26 13:40   ` Mark Cave-Ayland
  2026-08-26 13:58     ` Daniel P. Berrangé
  2026-08-26 14:50     ` Yonggang Luo
@ 2026-08-26 20:41     ` Daniel Henrique Barboza
  2026-08-27  9:58       ` Daniel P. Berrangé
  2 siblings, 1 reply; 57+ messages in thread
From: Daniel Henrique Barboza @ 2026-08-26 20:41 UTC (permalink / raw)
  To: Mark Cave-Ayland, Daniel P. Berrangé, Yonggang Luo
  Cc: qemu-devel, Xianglai Li, Alistair Francis, Chinmay Rath,
	Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu, Eric Farman,
	Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny



On 8/26/2026 10:40 AM, Mark Cave-Ayland wrote:
> On 26/08/2026 13:32, Daniel P. Berrangé wrote:
> 
>> On Sun, Aug 23, 2026 at 11:07:18PM +0800, Yonggang Luo wrote:
>>
>> snip,
>>
>> ..to comment just on the end result for now..
>>
>>> The last patch builds qemu-system (and qemu-systemw on Windows) from
>>> aarch64 common/system objects plus RISC-V arch objects, and installs
>>> qemu-system-{arm,aarch64,riscv32,riscv64} as symlinks so argv[0] still
>>> selects TargetInfo.
>>>
>>> Examples:
>>>
>>>    qemu-system -target aarch64 -M virt ...
>>>    qemu-system-riscv64 -M virt ...
>>>
>>> A basename that matches no registered token falls through to the unique
>>> default. A combined binary with no suffix requires -target when more
>>> than one default TargetInfo is registered.
>>
>> In testing and comparing  the new qemu-system-riscv64 symlink
>> to qemu-system vs the current standalone qemu-system-riscv64
>> binary there are some significant user visible changes.
>>
>> The simplest is 'qom-list-types' went from reporting approx
>> 770 classes, to reporting approx 1530 classes. IOW, the
>> qemu-system-riscv64 binary is now reporting supporting for
>> all the classes that were unique to arm.
>>
>> The '-device help' output similarly shows a great many more
>> devices
>>
>> TL;DR introspecting qemu-system-riscv64 is no longer accurate
>> wrt riscv64 capabilities.
>>
>> This is not suprising, since we register all TypeInfo meaning
>> we get all QOM classes present. Some of Pierricks patches try
>> to filter places which iterate over classes, but this does not
>> have full coverage.
>>
>>
>> I think this is probably also what leads to the increased RAM
>> usage in qemu-system-riscv64. Starting
>>
>>    qemu-system-riscv64 -nodefaults -display none -M none
>>
>> shows an increase in RAM usage from  17.3 to 20.7 MB which
>> is about 15% increase. NB this is dirty, private RAM per
>> process. The shared RAM pages also increase but that's not
>> a concern since they're common to all QEMU processes.
>>
>> qemu-system-aarch64 shows a much smaller RAM increase, since
>> it only grew from 1430 classes to 1530 classes.
>>
>> We have many more target though, so if we assume the end
>> point where every single target is unified, the the union
>> of all classes for all targets comes to approx 3600.
>>
>> My guesstimate is that would mean a memory increase for
>> qemu-system-riscv64 from 17.3 to 39.9 MB, which is a
>> 72% increase.
>>
>> In absolute terms this is still modest, but for deployments
>> with large VM counts  and small RAM sizes, that gets to be
>> significant.
>>
>>
>> None of this means single binary is a bad idea.
>>
>>
>> My main takeaway is that we're creating uneccessary work
>> for ourselves by trying to make 'qemu-sytem' identical
>> in behaviour to qemu-system-$TARGET.
>>
>> The complex filtering patches / QOM interfaces that I
>> found uncomfortable in Pierrick's base series are largely
>> around the filtering needed to simulate qemu-system-$TARGET,
>> and they're still incomplete. I don't have high confidence
>> in our ability to avoid regressions if we go route this
>> route.
>>
>>
>> IMHO we should make a clean break with the past. Leave
>> the existing qemu-system-$TARGET binaries being built
>> from the same pieces they are today, such that there
>> is better confidence that we are not making behavioural
>> changes to them.
>>
>>
>> qemu-system should be built alongside qemu-system-$TARGET
>> and offer new semantics where it is documented as exposing
>> everything from all targets whenever introspected and does
>> not apply target type or target Kconfig filtering to inputs/
>> outputs.
>>
>> We still get the benefit of only building most  .o files
>> once, so keeping qemu-system-$TARGET is only a small
>> overhead in the final step of linking everything together.
>>
>>
>> qemu-system will still have the increased memory overhead
>> but that's fine as qemu-system-$TARGET will be unaffected.
>> We can tackle the memory overhead of qemu-system at our
>> leisure through use of loadable modules, and thus not have
>> that as a task to think about today.
>>
>>
>> With the clean break with the past, we also have the
>> ability to tackle various long standing design mistakes
>> present in qemu-system-$TARGET instead of carrying them
>> over into the new binary.
>>
>> Specifically
>>
>>   * -nodefaults should become the default
>>   * All CLI args should be processed in order from
>>     the command line, so we eliminate the nonsense
>>     where we process some -object, then -chardev,
>>     then more -object through hand crafted deps
>>
>>   * No default machine type
> 
> I would even go as far as to suggest that we should make modules mandatory for qemu-system, so that devices can be loaded upon demand during machine construction to help keep the size down.
> 
> I'll leave whether that is through dependency tracking or via an explicit load directive for someone else to decide :)
>>   * Drop all legacy syntax so we only have a single
>>     QAPI based way of configuring.
>>     eg drop -hda, -hdb, -cdrom, -drive, etc
>>        only keeping -blockdev
>>     eg drop -mon, -monitor, -qmp, etc only
>>        keeping -object
> 
> The only problem with this is that I often get a lot of complaints that QEMU command lines are complicated from retro folks who just want to run their favourite old games. Why would they want to come up with a long-winded -drive command line when they can just use -hda instead?
> 
>> We don't have to do all that straightaway. If we declare
>> qemu-system "experimental" initially we can iterate on
>> that intentionally breaking compat in releases, without
>> any impact on qemu-system-$TARGET.
>>
>> Avoiding the back compat task will give us more flexibility
>> with the follow on work when people come to create new
>> machine types with heterogenous CPU targets.
> I agree that this is a good opportunity to explore new things without being tied to past decisions.

To be fair I don't think Phil and Pierrick are basing their design solely
on "we must comply to what qemu-system-$target does and has".  From what I
understood they're trying to get the prototype out of the door to prove that
it works, i.e. "this is clearest and most viable path we're seeing to make it
happen". This would naturally adhere to what is already available because,
well, it's already a proven base to build on top of.

I believe we'll end up doing a break with the past and experimenting a lot with
it (we definitely should mark it as experimental for multiple releases ...).
I also believe that there will be things we'll figure out only after the POC
lands, so might as well strive to get to that point ASAP.


Cheers,
dhb

> 
> 
> ATB,
> 
> Mark.
> 



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-26 18:35   ` Pierrick Bouvier
  2026-08-26 18:53     ` Pierrick Bouvier
@ 2026-08-27  9:44     ` Daniel P. Berrangé
  2026-08-27 16:32       ` Pierrick Bouvier
  2026-08-27 10:22     ` Daniel P. Berrangé
  2 siblings, 1 reply; 57+ messages in thread
From: Daniel P. Berrangé @ 2026-08-27  9:44 UTC (permalink / raw)
  To: Pierrick Bouvier
  Cc: Yonggang Luo, qemu-devel, Xianglai Li, Alistair Francis,
	Chinmay Rath, Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu,
	Eric Farman, Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Wed, Aug 26, 2026 at 11:35:11AM -0700, Pierrick Bouvier wrote:
> Seems like the Genius.Artist. in the bottle just need to escape, and you
> can send us a nice series doing all this. Meanwhile, I'll try to find a
> carpet, a monkey, a princess and a suit to be the next Aladdin.

This kind of comment is not productive and disrepectful to the time
reviewers in invest in looking at the proposed patches. Please stop
this.

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] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-26 20:41     ` Daniel Henrique Barboza
@ 2026-08-27  9:58       ` Daniel P. Berrangé
  0 siblings, 0 replies; 57+ messages in thread
From: Daniel P. Berrangé @ 2026-08-27  9:58 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: Mark Cave-Ayland, Yonggang Luo, qemu-devel, Xianglai Li,
	Alistair Francis, Chinmay Rath, Sunil V L, qemu-riscv,
	Alexander Bulekov, Zhao Liu, Eric Farman, Laurent Vivier,
	Peter Maydell, Chao Liu, Liu Zhiwei, Palmer Dabbelt, Song Gao,
	Harsh Prateek Bora, Glenn Miles, Pierrick Bouvier, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Wed, Aug 26, 2026 at 05:41:30PM -0300, Daniel Henrique Barboza wrote:
> 
> 
> On 8/26/2026 10:40 AM, Mark Cave-Ayland wrote:
> > On 26/08/2026 13:32, Daniel P. Berrangé wrote:
> > 
> > > On Sun, Aug 23, 2026 at 11:07:18PM +0800, Yonggang Luo wrote:
> > > 
> > > snip,
> > > 
> > > ..to comment just on the end result for now..
> > > 
> > > > The last patch builds qemu-system (and qemu-systemw on Windows) from
> > > > aarch64 common/system objects plus RISC-V arch objects, and installs
> > > > qemu-system-{arm,aarch64,riscv32,riscv64} as symlinks so argv[0] still
> > > > selects TargetInfo.
> > > > 
> > > > Examples:
> > > > 
> > > >    qemu-system -target aarch64 -M virt ...
> > > >    qemu-system-riscv64 -M virt ...
> > > > 
> > > > A basename that matches no registered token falls through to the unique
> > > > default. A combined binary with no suffix requires -target when more
> > > > than one default TargetInfo is registered.
> > > 
> > > In testing and comparing  the new qemu-system-riscv64 symlink
> > > to qemu-system vs the current standalone qemu-system-riscv64
> > > binary there are some significant user visible changes.
> > > 
> > > The simplest is 'qom-list-types' went from reporting approx
> > > 770 classes, to reporting approx 1530 classes. IOW, the
> > > qemu-system-riscv64 binary is now reporting supporting for
> > > all the classes that were unique to arm.
> > > 
> > > The '-device help' output similarly shows a great many more
> > > devices
> > > 
> > > TL;DR introspecting qemu-system-riscv64 is no longer accurate
> > > wrt riscv64 capabilities.
> > > 
> > > This is not suprising, since we register all TypeInfo meaning
> > > we get all QOM classes present. Some of Pierricks patches try
> > > to filter places which iterate over classes, but this does not
> > > have full coverage.
> > > 
> > > 
> > > I think this is probably also what leads to the increased RAM
> > > usage in qemu-system-riscv64. Starting
> > > 
> > >    qemu-system-riscv64 -nodefaults -display none -M none
> > > 
> > > shows an increase in RAM usage from  17.3 to 20.7 MB which
> > > is about 15% increase. NB this is dirty, private RAM per
> > > process. The shared RAM pages also increase but that's not
> > > a concern since they're common to all QEMU processes.
> > > 
> > > qemu-system-aarch64 shows a much smaller RAM increase, since
> > > it only grew from 1430 classes to 1530 classes.
> > > 
> > > We have many more target though, so if we assume the end
> > > point where every single target is unified, the the union
> > > of all classes for all targets comes to approx 3600.
> > > 
> > > My guesstimate is that would mean a memory increase for
> > > qemu-system-riscv64 from 17.3 to 39.9 MB, which is a
> > > 72% increase.
> > > 
> > > In absolute terms this is still modest, but for deployments
> > > with large VM counts  and small RAM sizes, that gets to be
> > > significant.
> > > 
> > > 
> > > None of this means single binary is a bad idea.
> > > 
> > > 
> > > My main takeaway is that we're creating uneccessary work
> > > for ourselves by trying to make 'qemu-sytem' identical
> > > in behaviour to qemu-system-$TARGET.
> > > 
> > > The complex filtering patches / QOM interfaces that I
> > > found uncomfortable in Pierrick's base series are largely
> > > around the filtering needed to simulate qemu-system-$TARGET,
> > > and they're still incomplete. I don't have high confidence
> > > in our ability to avoid regressions if we go route this
> > > route.
> > > 
> > > 
> > > IMHO we should make a clean break with the past. Leave
> > > the existing qemu-system-$TARGET binaries being built
> > > from the same pieces they are today, such that there
> > > is better confidence that we are not making behavioural
> > > changes to them.
> > > 
> > > 
> > > qemu-system should be built alongside qemu-system-$TARGET
> > > and offer new semantics where it is documented as exposing
> > > everything from all targets whenever introspected and does
> > > not apply target type or target Kconfig filtering to inputs/
> > > outputs.
> > > 
> > > We still get the benefit of only building most  .o files
> > > once, so keeping qemu-system-$TARGET is only a small
> > > overhead in the final step of linking everything together.
> > > 
> > > 
> > > qemu-system will still have the increased memory overhead
> > > but that's fine as qemu-system-$TARGET will be unaffected.
> > > We can tackle the memory overhead of qemu-system at our
> > > leisure through use of loadable modules, and thus not have
> > > that as a task to think about today.
> > > 
> > > 
> > > With the clean break with the past, we also have the
> > > ability to tackle various long standing design mistakes
> > > present in qemu-system-$TARGET instead of carrying them
> > > over into the new binary.
> > > 
> > > Specifically
> > > 
> > >   * -nodefaults should become the default
> > >   * All CLI args should be processed in order from
> > >     the command line, so we eliminate the nonsense
> > >     where we process some -object, then -chardev,
> > >     then more -object through hand crafted deps
> > > 
> > >   * No default machine type
> > 
> > I would even go as far as to suggest that we should make modules mandatory for qemu-system, so that devices can be loaded upon demand during machine construction to help keep the size down.
> > 
> > I'll leave whether that is through dependency tracking or via an explicit load directive for someone else to decide :)
> > >   * Drop all legacy syntax so we only have a single
> > >     QAPI based way of configuring.
> > >     eg drop -hda, -hdb, -cdrom, -drive, etc
> > >        only keeping -blockdev
> > >     eg drop -mon, -monitor, -qmp, etc only
> > >        keeping -object
> > 
> > The only problem with this is that I often get a lot of complaints that QEMU command lines are complicated from retro folks who just want to run their favourite old games. Why would they want to come up with a long-winded -drive command line when they can just use -hda instead?
> > 
> > > We don't have to do all that straightaway. If we declare
> > > qemu-system "experimental" initially we can iterate on
> > > that intentionally breaking compat in releases, without
> > > any impact on qemu-system-$TARGET.
> > > 
> > > Avoiding the back compat task will give us more flexibility
> > > with the follow on work when people come to create new
> > > machine types with heterogenous CPU targets.
> > I agree that this is a good opportunity to explore new things without being tied to past decisions.
> 
> To be fair I don't think Phil and Pierrick are basing their design solely
> on "we must comply to what qemu-system-$target does and has".  From what I
> understood they're trying to get the prototype out of the door to prove that
> it works, i.e. "this is clearest and most viable path we're seeing to make it
> happen". This would naturally adhere to what is already available because,
> well, it's already a proven base to build on top of.

In looking at these patches my impression is introducing "qemu-system"
as its own thing is simpler than trying to make 'qemu-system' be able
to replace & simulate qemu-system-$target, which this does.

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] 57+ messages in thread

* Re: [PATCH 10/12] target-info: add -target and program-name selection
  2026-08-26 18:13     ` Pierrick Bouvier
@ 2026-08-27 10:13       ` Daniel P. Berrangé
  0 siblings, 0 replies; 57+ messages in thread
From: Daniel P. Berrangé @ 2026-08-27 10:13 UTC (permalink / raw)
  To: Pierrick Bouvier
  Cc: Yonggang Luo, qemu-devel, Xianglai Li, Alistair Francis,
	Chinmay Rath, Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu,
	Eric Farman, Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Wed, Aug 26, 2026 at 11:13:05AM -0700, Pierrick Bouvier wrote:
> On 8/26/2026 5:46 AM, Daniel P. Berrangé wrote:
> By implementing *strict* identical behavior with existing binaries, we
> indeed didn't add any new feature, but:
> - we reduced total number of compilation units by 30%
> - we cleaned up a lot of headers and did a lot of refactoring
> - we have a systematic approach to add new targets in single-binary
> while being able to reuse all existing tests without any change.
>
> From my point of view, what you see as a detour was precisely what made
> us progress so far in a year.

No, on the contrary, that's all good stuff.

What I'm considering here is the behaviour of the new proposed
qemu-system and what it needs to be able todo.

Some of this work only appears relevant to a scenario where
qemu-system-$target is dropped in favour of a symlink to the
new qemu-system. That forces qemu-system to be 100% compatible
with the existing binaries, which IMHO is an undesirable
constraint and creates extra work.

We can have the benefits of the compliation unit reduction,
cleaner headers, etc, while still having qemu-system be a
distinct break with the past in a number of areas.

> > If we ignore historical compat and treat qemu-system as a
> > clean break, then I'd suggest that 'target' is not a concept
> > to be exposed to the user at all.
> >
> 
> If your only problem is with having a new -target option, I would be
> happy to just keep the behavior to derive the target from current binary
> name. That's a very small compromise on my side, and -target is just
> here for convenience. It's not the end of the path.

It isn't about the syntax - whether it is implicit from the binary
name or explicit from -target, that's still producing a design
where the target is the top level concept, and machine is a second
level concept. I don't see how that makes sense given the longer
term intent to have machines with heterogeneous CPU targets.

The machine looks like it should be the top level concept, with
target(s) derived from that.

> > The user cares about the machine (and CPUs) they want to run,
> > and their choice in this respect is what should determine the
> > target(s) QEMU needs to enable. We should take
> > 
> >   qemu-system --machine vexpress-a15
> > 
> > that tells us we need the arm target. If we need to distinguish
> > arm7 vs aarch64, then the choice of -cpu should determine 32
> > bs 64 bit.
> > 
> > This extends better into the future world where we have
> > machine type that could involve CPUs from multiple targets.
> > 
> > IOW machine config option / QOM class is what we should pivot
> > off rather than a global target config option.
> > 
> > This likely implies that the MachineClass should gain a class
> > method to query the QEMU_ARCH_XXXX bitmask required. Initially
> > restricted to only a single target, so you can wire that through
> > to the current global target info at startup. Later expanded to
> > support multiple concurrent targets.
> >
> 
> While it sounds nice on paper, you will be doomed to ambiguity with this:
> 
> qemu-system -machine virt -cpu max
> 
> What is your next plan? add an environment variable to solve it?

The machine names need to be globally unique across all targets.
So the 'virt' naming clash needs a rename, such as is done in
an earlier patch in this series.

> Deriving target from argv(0) or -target is explicit, predictable, boring
> and reliable, and it's exactly what we need now.

With the requirement that machine names are globally unique, we can
determine the target(s) directly.

Relying on argv(0) does not appear to work in a heterogeneous future
as target is no longer unique per process, but the machine type would
be unique.

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] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-26 18:35   ` Pierrick Bouvier
  2026-08-26 18:53     ` Pierrick Bouvier
  2026-08-27  9:44     ` Daniel P. Berrangé
@ 2026-08-27 10:22     ` Daniel P. Berrangé
  2 siblings, 0 replies; 57+ messages in thread
From: Daniel P. Berrangé @ 2026-08-27 10:22 UTC (permalink / raw)
  To: Pierrick Bouvier
  Cc: Yonggang Luo, qemu-devel, Xianglai Li, Alistair Francis,
	Chinmay Rath, Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu,
	Eric Farman, Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Wed, Aug 26, 2026 at 11:35:11AM -0700, Pierrick Bouvier wrote:
> On 8/26/2026 5:32 AM, Daniel P. Berrangé wrote:
> > I think this is probably also what leads to the increased RAM
> > usage in qemu-system-riscv64. Starting
> > 
> >   qemu-system-riscv64 -nodefaults -display none -M none
> > 
> > shows an increase in RAM usage from  17.3 to 20.7 MB which
> > is about 15% increase. NB this is dirty, private RAM per
> > process. The shared RAM pages also increase but that's not
> > a concern since they're common to all QEMU processes.
> > 
> > qemu-system-aarch64 shows a much smaller RAM increase, since
> > it only grew from 1430 classes to 1530 classes.
> > 
> > We have many more target though, so if we assume the end
> > point where every single target is unified, the the union
> > of all classes for all targets comes to approx 3600.
> > 
> > My guesstimate is that would mean a memory increase for
> > qemu-system-riscv64 from 17.3 to 39.9 MB, which is a
> > 72% increase.
> > 
> > In absolute terms this is still modest, but for deployments
> > with large VM counts  and small RAM sizes, that gets to be
> > significant.
> >
> 
> How surprising (:eye-roll:) it is that adding more code and more classes
> would result in a higher memory usage, or bigger binary size for
> qemu-system.

It is not a surprise, I'm just examining the effect.

> More seriously. If someone is concerned about it, the simple solution is
> to restrict list of targets and/or Kconfig to include less.

Building custom minimized QEMU is not a path that works for
distro vendors, as we can't tailor to distinct use cases,
so the footprint of the generic build and any impact on our
packaging is a factor I'm interested in.

The 'modules' feature came out of our work to lower the
footprint of a default "all features" QEMU build.

As long as qemu-system-$target stays around as its current
impl, it isn't a blocker. If qemu-system-$target were changed
into a symlink to qemu-system, then it becomes a critical path
problem for the distro packaging.

I think the solution long term is to further expand the use
of modules to more of the code.

> > IMHO we should make a clean break with the past. Leave
> > the existing qemu-system-$TARGET binaries being built
> > from the same pieces they are today, such that there
> > is better confidence that we are not making behavioural
> > changes to them.
> >
> 
> Funny enough, it reminded me word for word of a blog post from a
> Microsoft employee where he explained that powershell existed only
> because young developers were scared to modify original cmd shell.
> 
> Regression issues are solved with testing and good design, not by
> inventing new things.

We don't have sufficient testing, nor is the current QEMU
qemu-system-$target especially good from a design POV as
it has decades of historical baggage holding us back. The
introduction of a new binary is the ideal time to address
this long term problem. It frees us to do changes that are
otherwise impossible and to experiment with new ideas
without worrying about implications for the current binaries
and their users.

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] 57+ messages in thread

* Re: [PATCH 10/12] target-info: add -target and program-name selection
  2026-08-26 12:46   ` Daniel P. Berrangé
  2026-08-26 18:13     ` Pierrick Bouvier
@ 2026-08-27 12:25     ` Daniel P. Berrangé
  1 sibling, 0 replies; 57+ messages in thread
From: Daniel P. Berrangé @ 2026-08-27 12:25 UTC (permalink / raw)
  To: Yonggang Luo, qemu-devel, Xianglai Li, Alistair Francis,
	Chinmay Rath, Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu,
	Eric Farman, Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, Pierrick Bouvier, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Wed, Aug 26, 2026 at 01:46:17PM +0100, Daniel P. Berrangé wrote:
> On Sun, Aug 23, 2026 at 11:07:28PM +0800, Yonggang Luo wrote:
> > - Parse -target before TargetInfo is fixed; CLI overrides the program
> >   basename.
> > - Tokens are target_name or target_name-be / -le; -target help lists
> >   registered names in sorted order.
> > - When -target is omitted, infer the token from g_get_prgname(): strip
> >   .exe, take the longest dash-separated registered suffix, and retry
> >   without a trailing w for Windows GUI binaries.
> > - A basename that matches no registered token falls through to the
> >   unique default. Combined binaries with no suffix require -target
> >   when more than one default TargetInfo is registered.
> 
> IMHO this -target argument and the target interference from
> program name is a mistaken direction.  We're being led off
> course by the attempt to make the new qemu-system be identical
> to qemu-system-$TARGET.
> 
> If we ignore historical compat and treat qemu-system as a
> clean break, then I'd suggest that 'target' is not a concept
> to be exposed to the user at all.
> 
> The user cares about the machine (and CPUs) they want to run,
> and their choice in this respect is what should determine the
> target(s) QEMU needs to enable. We should take
> 
>   qemu-system --machine vexpress-a15
> 
> that tells us we need the arm target. If we need to distinguish
> arm7 vs aarch64, then the choice of -cpu should determine 32
> bs 64 bit.
> 
> This extends better into the future world where we have
> machine type that could involve CPUs from multiple targets.
> 
> IOW machine config option / QOM class is what we should pivot
> off rather than a global target config option.

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.


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] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-27  9:44     ` Daniel P. Berrangé
@ 2026-08-27 16:32       ` Pierrick Bouvier
  2026-08-27 17:42         ` Peter Maydell
  2026-08-27 17:48         ` Paolo Bonzini
  0 siblings, 2 replies; 57+ messages in thread
From: Pierrick Bouvier @ 2026-08-27 16:32 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Yonggang Luo, qemu-devel, Xianglai Li, Alistair Francis,
	Chinmay Rath, Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu,
	Eric Farman, Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On 8/27/2026 2:44 AM, Daniel P. Berrangé wrote:
> On Wed, Aug 26, 2026 at 11:35:11AM -0700, Pierrick Bouvier wrote:
>> Seems like the Genius.Artist. in the bottle just need to escape, and you
>> can send us a nice series doing all this. Meanwhile, I'll try to find a
>> carpet, a monkey, a princess and a suit to be the next Aladdin.
> 
> This kind of comment is not productive and disrepectful to the time
> reviewers in invest in looking at the proposed patches. Please stop
> this.
>

The only person wasting everyone's time here is YOU.
There is not a single person who came on any thread to say "I agree with
you Daniel", while several posted or commented they were ok with the
approach here.

Project is QEMU, not Daniel's EMU.

Whether or not you like my joke above does not matter, just focus on the
first sentence of it. Send a series implementing your view instead of
long emails "I said so" on other people series. And go back to the lamp
until it's ready.

> With regards,
> Daniel

Regards,
Pierrick


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-27 16:32       ` Pierrick Bouvier
@ 2026-08-27 17:42         ` Peter Maydell
  2026-08-27 17:48         ` Paolo Bonzini
  1 sibling, 0 replies; 57+ messages in thread
From: Peter Maydell @ 2026-08-27 17:42 UTC (permalink / raw)
  To: Pierrick Bouvier
  Cc: Daniel P. Berrangé, Yonggang Luo, qemu-devel, Xianglai Li,
	Alistair Francis, Chinmay Rath, Sunil V L, qemu-riscv,
	Alexander Bulekov, Zhao Liu, Eric Farman, Laurent Vivier,
	Chao Liu, Liu Zhiwei, Palmer Dabbelt, Song Gao,
	Harsh Prateek Bora, Glenn Miles, Daniel Henrique Barboza,
	qemu-s390x, Jiaxun Yang, Philippe Mathieu-Daudé,
	Michael S. Tsirkin, Stefan Hajnoczi, Alex Bennée,
	David Hildenbrand, qemu-ppc, qemu-arm, Igor Mammedov,
	Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Paolo Bonzini, Ani Sinha, Bibo Mao,
	Marc-André Lureau, Matthew Rosato, Weiwei Li, Darren Kenny

On Thu, 27 Aug 2026 at 17:32, Pierrick Bouvier
<pierrick.bouvier@oss.qualcomm.com> wrote:
>
> On 8/27/2026 2:44 AM, Daniel P. Berrangé wrote:
> > On Wed, Aug 26, 2026 at 11:35:11AM -0700, Pierrick Bouvier wrote:
> >> Seems like the Genius.Artist. in the bottle just need to escape, and you
> >> can send us a nice series doing all this. Meanwhile, I'll try to find a
> >> carpet, a monkey, a princess and a suit to be the next Aladdin.
> >
> > This kind of comment is not productive and disrepectful to the time
> > reviewers in invest in looking at the proposed patches. Please stop
> > this.
> >
>
> The only person wasting everyone's time here is YOU.
> There is not a single person who came on any thread to say "I agree with
> you Daniel", while several posted or commented they were ok with the
> approach here.
>
> Project is QEMU, not Daniel's EMU.
>
> Whether or not you like my joke above does not matter, just focus on the
> first sentence of it. Send a series implementing your view instead of
> long emails "I said so" on other people series. And go back to the lamp
> until it's ready.

Pierrick: please calm down and take a less confrontational attitude
in your mailing list posts. Daniel is reviewing the code, which is part
of the project's process. He hasn't done anything here that merits
the sniping you've been doing in this thread.

This is entirely separate from any technical issues about what the
best approach here is.

-- PMM


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-27 16:32       ` Pierrick Bouvier
  2026-08-27 17:42         ` Peter Maydell
@ 2026-08-27 17:48         ` Paolo Bonzini
  2026-08-27 19:58           ` Pierrick Bouvier
  1 sibling, 1 reply; 57+ messages in thread
From: Paolo Bonzini @ 2026-08-27 17:48 UTC (permalink / raw)
  To: Pierrick Bouvier
  Cc: Daniel P. Berrangé, Yonggang Luo, qemu-devel, Xianglai Li,
	Alistair Francis, Chinmay Rath, Sunil V L, qemu-riscv,
	Alexander Bulekov, Zhao Liu, Eric Farman, Laurent Vivier,
	Peter Maydell, Chao Liu, Liu Zhiwei, Palmer Dabbelt, Song Gao,
	Harsh Prateek Bora, Glenn Miles, Daniel Henrique Barboza,
	qemu-s390x, Jiaxun Yang, Philippe Mathieu-Daudé,
	Michael S. Tsirkin, Stefan Hajnoczi, Alex Bennée,
	David Hildenbrand, qemu-ppc, qemu-arm, Igor Mammedov,
	Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Ani Sinha, Bibo Mao, Marc-André Lureau,
	Matthew Rosato, Weiwei Li, Darren Kenny

On Thu, Aug 27, 2026 at 6:32 PM Pierrick Bouvier
<pierrick.bouvier@oss.qualcomm.com> wrote:
>
> On 8/27/2026 2:44 AM, Daniel P. Berrangé wrote:
> > On Wed, Aug 26, 2026 at 11:35:11AM -0700, Pierrick Bouvier wrote:
> >> Seems like the Genius.Artist. in the bottle just need to escape, and you
> >> can send us a nice series doing all this. Meanwhile, I'll try to find a
> >> carpet, a monkey, a princess and a suit to be the next Aladdin.
> >
> > This kind of comment is not productive and disrepectful to the time
> > reviewers in invest in looking at the proposed patches. Please stop
> > this.
> >
>
> The only person wasting everyone's time here is YOU.
> There is not a single person who came on any thread to say "I agree with
> you Daniel", while several posted or commented they were ok with the
> approach here.
>
> Project is QEMU, not Daniel's EMU.

Whoa whoa.

Sometimes people don't reply not because they disagree, but because
they trust the people involved to resolve the problem.

Let me remind you of the discussion we had about -fms-bitfields and
how it was resolved amicably and profitably.

I will read the thread and try to understand what's going on but from
the first impression, "wanting to keep the single-system
qemu-system-riscv64 instead of a symlink" is a valid objection. In
fact, with the proviso that I haven't read the code, I don't see why
you'd want *anything else*.

And especially, "How surprising (:eye-roll:) it is that adding more
code and more classes would result in a higher memory usage, or bigger
binary size for qemu-system" is not a good way to conduct a
discussion.

This project was extremely complex and some disagreements are normal,
but overall I would say it has received support from the community for
years. It is close to the finish line, let's not forget all the
collaboration so far.

Paolo



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-26 12:32 ` Daniel P. Berrangé
  2026-08-26 13:40   ` Mark Cave-Ayland
  2026-08-26 18:35   ` Pierrick Bouvier
@ 2026-08-27 17:59   ` Paolo Bonzini
  2026-08-28  5:44     ` Yonggang Luo
  2 siblings, 1 reply; 57+ messages in thread
From: Paolo Bonzini @ 2026-08-27 17:59 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Yonggang Luo, qemu-devel, Xianglai Li, Alistair Francis,
	Chinmay Rath, Sunil V L, qemu-riscv, Alexander Bulekov, Zhao Liu,
	Eric Farman, Laurent Vivier, Peter Maydell, Chao Liu, Liu Zhiwei,
	Palmer Dabbelt, Song Gao, Harsh Prateek Bora, Glenn Miles,
	Daniel Henrique Barboza, Pierrick Bouvier, qemu-s390x,
	Jiaxun Yang, Philippe Mathieu-Daudé, Michael S. Tsirkin,
	Stefan Hajnoczi, Alex Bennée, David Hildenbrand, qemu-ppc,
	qemu-arm, Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin,
	Cornelia Huck, Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Ani Sinha, Bibo Mao, Marc-André Lureau,
	Matthew Rosato, Weiwei Li, Darren Kenny

On Wed, Aug 26, 2026 at 2:33 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
> With the clean break with the past, we also have the
> ability to tackle various long standing design mistakes
> present in qemu-system-$TARGET instead of carrying them
> over into the new binary.

I am not sure about this. Overall most (not all) of the complexity of
command-line processing and legacy arguments is kept at bay, and
contained within board code - and boards do not have to support it.

The complexity that is left is tied to -drive, mostly due to
differences between hot-unplug in -drive and -blockdev. And honestly
I'd be very much opposed to dropping -drive because using -blockdev
correctly is *extremely* hard and barely documented.

If we want a clean break, we need to drop the command line completely
and just have a QMP monitor on stdin/stdout
(https://wiki.qemu.org/User:Paolo_Bonzini/Machine_init_sequence).
Start small adding just accel-new and machine-new, and add QMP
equivalents of command line objects as needed.

That said, I understand that this is just an idea and not the crux of
the disagreement.

Paolo



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-27 17:48         ` Paolo Bonzini
@ 2026-08-27 19:58           ` Pierrick Bouvier
  2026-09-04 12:47             ` Paolo Bonzini
  0 siblings, 1 reply; 57+ messages in thread
From: Pierrick Bouvier @ 2026-08-27 19:58 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Daniel P. Berrangé, Yonggang Luo, qemu-devel, Xianglai Li,
	Alistair Francis, Chinmay Rath, Sunil V L, qemu-riscv,
	Alexander Bulekov, Zhao Liu, Eric Farman, Laurent Vivier,
	Peter Maydell, Chao Liu, Liu Zhiwei, Palmer Dabbelt, Song Gao,
	Harsh Prateek Bora, Glenn Miles, Daniel Henrique Barboza,
	qemu-s390x, Jiaxun Yang, Philippe Mathieu-Daudé,
	Michael S. Tsirkin, Stefan Hajnoczi, Alex Bennée,
	David Hildenbrand, qemu-ppc, qemu-arm, Igor Mammedov,
	Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Ani Sinha, Bibo Mao, Marc-André Lureau,
	Matthew Rosato, Weiwei Li, Darren Kenny

On 8/27/2026 10:48 AM, Paolo Bonzini wrote:
> On Thu, Aug 27, 2026 at 6:32 PM Pierrick Bouvier
> <pierrick.bouvier@oss.qualcomm.com> wrote:
>>
>> On 8/27/2026 2:44 AM, Daniel P. Berrangé wrote:
>>> On Wed, Aug 26, 2026 at 11:35:11AM -0700, Pierrick Bouvier wrote:
>>>> Seems like the Genius.Artist. in the bottle just need to escape, and you
>>>> can send us a nice series doing all this. Meanwhile, I'll try to find a
>>>> carpet, a monkey, a princess and a suit to be the next Aladdin.
>>>
>>> This kind of comment is not productive and disrepectful to the time
>>> reviewers in invest in looking at the proposed patches. Please stop
>>> this.
>>>
>>
>> The only person wasting everyone's time here is YOU.
>> There is not a single person who came on any thread to say "I agree with
>> you Daniel", while several posted or commented they were ok with the
>> approach here.
>>
>> Project is QEMU, not Daniel's EMU.
>
> Whoa whoa.
> 

I apologize to Daniel, and other people on this thread for resorting to
sarcasm in this situation, and personally mention Daniel in my answer.

It stems from the fact that it's not the first time Daniel come on a
thread to push a view (that might be wrong) and don't listen to other's
people opinion, or leave the conversation when he has no more arguments
or discover he's wrong. I'm not the first one to discover this, and it's
a topic that came from multiple people I met. I invite anyone to tell me
publicly it's in my head, and that it is wrong.
Neuroatypicality does *not* justify passive-aggressive behavior. We have
many examples in the community of neuroatypical members that still are
open to different opinions, and don't act this way.
I don't see it as collaboration but as "I've been there before you, so
do what I say", which has absolutely no technical basis, like it should
in our community.
I don't know how to fix the behavior described above, but since Peter
and you manage the community, I'm open to discuss about it. I'm also
open to hear "Pierrick, you are the problem", apologize and accept it,
learn and keep on working with all of you.

In all cases, it does not justify any personal attack, so sorry again
about this, it won't happen again.

> Sometimes people don't reply not because they disagree, but because
> they trust the people involved to resolve the problem.
>

We presented a plan a year ago, for which multiple people have been
supportive in general. Now we are close to having a single binary
upstream, we have Daniel coming last minute and asking to solve issues
we are not at yet. I feel it's not helping us, and simply blocking work.

Daniel's main concern (correct me if I'm wrong), is that we might
introduce regressions by introducing a -target option, and filtering on
QOM types. I don't see where it is a problem. Even if a mistake comes,
it takes a single patch to fix the missing type. So I asked several
times to postpone his desire to refactor things, but he keeps on coming
and blocking work going any different direction.

I have no problem with anyone deciding to refactor the QEMU command
line, but it's a different problem from what we are doing now.
We just want to provide a first version upstream mixing at least two
base architectures, and providing exact same behavior than existing
binaries.

> Let me remind you of the discussion we had about -fms-bitfields and
> how it was resolved amicably and profitably.
>

I really appreciated this exchange with you. Even if I was a newcomer,
you explained where you disagreed, but accepted a different answer. Then
we iterated to prove that existing struct layout were not impacted, and
we both observed it was safe to remove this option. I felt like we both
worked toward a goal, and not that you pushed your personal vision
without any technical basis.

> I will read the thread and try to understand what's going on but from
> the first impression, "wanting to keep the single-system
> qemu-system-riscv64 instead of a symlink" is a valid objection. In
> fact, with the proviso that I haven't read the code, I don't see why
> you'd want *anything else*.
>

There are other threads you might want to take a look at to have the
full picture:
- 20260821235112.193381-1-pierrick.bouvier@oss.qualcomm.com
- 20260724000948.234657-1-pierrick.bouvier@oss.qualcomm.com
-
https://patchew.org/QEMU/20260514172303.1484273-1-pierrick.bouvier@oss.qualcomm.com/
(v2-v4 for a concrete example of pushing things in a direction without
listening to arguments, and not follow up when discovering things are
wrong, thus blocking work).

> And especially, "How surprising (:eye-roll:) it is that adding more
> code and more classes would result in a higher memory usage, or bigger
> binary size for qemu-system" is not a good way to conduct a
> discussion.
>

I apologize again for sarcasm.

> This project was extremely complex and some disagreements are normal,
> but overall I would say it has received support from the community for
> years. It is close to the finish line, let's not forget all the
> collaboration so far.
>

At this point, I don't see the finish line coming anytime soon.
We are stuck in a situation where we now might have to design a whole
new command line from scratch, for a reason I ignore.
Meanwhile, we fix downstream regressions on single-binary, and it's
exhausting.

I would appreciate if you, Peter, or Markus, could decide something
here, and explicitly say:
- let's go with original plan, and just introduce -target option and
call it a day for now. CLI refactoring can be initiated in parallel.
- let's change the original plan, and Daniel (or anyone willing to) can
design a new cli for this binary. I'm personally out of this.

I would also add that a new cli is completely unrelated to
single-binary/heterogeneous, and it could already be
designed/experimented with a single target, without impacting current work.

> Paolo
> 

Regards,
Pierrick


^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-27 17:59   ` Paolo Bonzini
@ 2026-08-28  5:44     ` Yonggang Luo
  0 siblings, 0 replies; 57+ messages in thread
From: Yonggang Luo @ 2026-08-28  5:44 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Daniel P. Berrangé, qemu-devel, Xianglai Li,
	Alistair Francis, Chinmay Rath, Sunil V L, qemu-riscv,
	Alexander Bulekov, Zhao Liu, Eric Farman, Laurent Vivier,
	Peter Maydell, Chao Liu, Liu Zhiwei, Palmer Dabbelt, Song Gao,
	Harsh Prateek Bora, Glenn Miles, Daniel Henrique Barboza,
	Pierrick Bouvier, qemu-s390x, Jiaxun Yang,
	Philippe Mathieu-Daudé, Michael S. Tsirkin, Stefan Hajnoczi,
	Alex Bennée, David Hildenbrand, qemu-ppc, qemu-arm,
	Igor Mammedov, Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Ani Sinha, Bibo Mao, Marc-André Lureau,
	Matthew Rosato, Weiwei Li, Darren Kenny

[-- Attachment #1: Type: text/plain, Size: 2949 bytes --]

On Fri, Aug 28, 2026 at 1:59 AM Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On Wed, Aug 26, 2026 at 2:33 PM Daniel P. Berrangé <berrange@redhat.com>
wrote:
> > With the clean break with the past, we also have the
> > ability to tackle various long standing design mistakes
> > present in qemu-system-$TARGET instead of carrying them
> > over into the new binary.



Paolo also said keeping qemu-system-riscv64 as a real binary, not a
symlink, is a valid objection.

v2 already takes that part:

  https://patchew.org/QEMU/20260826184229.1145-1-luoyonggang@gmail.com/

What v2 changed relative to v1:

- qemu-system-$TARGET is still a separately linked binary. qemu-system
  is extra, from the ARM + RISC-V union. v1 installed
  qemu-system-{arm,aarch64,riscv32,riscv64} as symlinks; that is gone.
- Bare qemu-system always requires -target. There is no unique-
  TargetInfo fallback.
- Dropped little- and big-endian TargetInfo variants from this series.
  One TargetInfo per target_name. Endian variants are later work.
- No qemu-systemw for the combined binary, so a Windows GUI twin does
  not block enabling modules later.

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

The per-target binaries should keep the same QOM list and RSS as today.
The extra RAM and incomplete filtering only apply to the extra
qemu-system binary.

v2 still uses -target and TYPE_TARGET_SPECIFIC on that combined binary.
It does not drop legacy CLI, and it does not mark qemu-system
experimental. I treated those as later work, not required to stop
replacing qemu-system-$TARGET with a symlink.


The v2 still based on TYPE_TARGET_SPECIFIC  changes from Pierrick Bouvier,
it's a great changes that
get target-info-def.c to be generic, so maybe we can review the v2 version
instead.

The v2 version can be merged without affecting existing qemu-system-*. if
something wrong v2, tell me in v2 patches.


>
> I am not sure about this. Overall most (not all) of the complexity of
> command-line processing and legacy arguments is kept at bay, and
> contained within board code - and boards do not have to support it.
>
> The complexity that is left is tied to -drive, mostly due to
> differences between hot-unplug in -drive and -blockdev. And honestly
> I'd be very much opposed to dropping -drive because using -blockdev
> correctly is *extremely* hard and barely documented.
>
> If we want a clean break, we need to drop the command line completely
> and just have a QMP monitor on stdin/stdout
> (https://wiki.qemu.org/User:Paolo_Bonzini/Machine_init_sequence).
> Start small adding just accel-new and machine-new, and add QMP
> equivalents of command line objects as needed.
>
> That said, I understand that this is just an idea and not the crux of
> the disagreement.
>
> Paolo
>


--
         此致
礼
罗勇刚
Yours
    sincerely,
Yonggang Luo

[-- Attachment #2: Type: text/html, Size: 3498 bytes --]

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-08-27 19:58           ` Pierrick Bouvier
@ 2026-09-04 12:47             ` Paolo Bonzini
  2026-09-14  5:46               ` Pierrick Bouvier
  0 siblings, 1 reply; 57+ messages in thread
From: Paolo Bonzini @ 2026-09-04 12:47 UTC (permalink / raw)
  To: Pierrick Bouvier
  Cc: Daniel P. Berrangé, Yonggang Luo, qemu-devel, Xianglai Li,
	Alistair Francis, Chinmay Rath, Sunil V L, qemu-riscv,
	Alexander Bulekov, Zhao Liu, Eric Farman, Laurent Vivier,
	Peter Maydell, Chao Liu, Liu Zhiwei, Palmer Dabbelt, Song Gao,
	Harsh Prateek Bora, Glenn Miles, Daniel Henrique Barboza,
	qemu-s390x, Jiaxun Yang, Philippe Mathieu-Daudé,
	Michael S. Tsirkin, Stefan Hajnoczi, Alex Bennée,
	David Hildenbrand, qemu-ppc, qemu-arm, Igor Mammedov,
	Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Ani Sinha, Bibo Mao, Marc-André Lureau,
	Matthew Rosato, Weiwei Li, Darren Kenny

On 8/27/26 21:58, Pierrick Bouvier wrote:
> On 8/27/2026 10:48 AM, Paolo Bonzini wrote:
>> Whoa whoa.
>>
> 
> I apologize to Daniel, and other people on this thread for resorting to
> sarcasm in this situation, and personally mention Daniel in my answer.
> 
> It stems from the fact that it's not the first time Daniel come on a
> thread to push a view (that might be wrong) and don't listen to other's
> people opinion, or leave the conversation when he has no more arguments
> or discover he's wrong. I'm not the first one to discover this, and it's
> a topic that came from multiple people I met. I invite anyone to tell me
> publicly it's in my head, and that it is wrong.

Please stop.  Just stop.  "It came from multiple people" never ends well.

I have my own disagreements with Daniel, which is no surprise since I've 
known him at work for over 15 years.  In fact, we probably had a couple 
just this week, though that's fortunately above average.  We have 
different personalities, we come from different cultural backgrounds. 
We are still able to respect each other and I seek his opinion even if 
(or sometimes because) I know it'll be different and make things harder 
for me. :)

>> Sometimes people don't reply not because they disagree, but because
>> they trust the people involved to resolve the problem.
> 
> We presented a plan a year ago, for which multiple people have been
> supportive in general. Now we are close to having a single binary
> upstream, we have Daniel coming last minute and asking to solve issues
> we are not at yet. I feel it's not helping us, and simply blocking work.
> 
> Daniel's main concern (correct me if I'm wrong), is that we might
> introduce regressions by introducing a -target option, and filtering on
> QOM types.

I'll briefly touch the technical part.  As it was explained, the problem 
is really just in the use of symlinks for aarch64 and riscv64 binaries.

All that Daniel is *asking for* is to split the experimental part from 
the existing one.  Did he go on a tangent on what else he'd like from 
the experimental part?  Yes, but that's simply a justification for why 
it's better to keep it split.

> I have no problem with anyone deciding to refactor the QEMU command
> line, but it's a different problem from what we are doing now.
> We just want to provide a first version upstream mixing at least two
> base architectures, and providing exact same behavior than existing
> binaries.

Yes, and that's fine.

>> Let me remind you of the discussion we had about -fms-bitfields and
>> how it was resolved amicably and profitably.
> 
> I really appreciated this exchange with you. Even if I was a newcomer,
> you explained where you disagreed, but accepted a different answer. Then
> we iterated to prove that existing struct layout were not impacted, and
> we both observed it was safe to remove this option. I felt like we both
> worked toward a goal, and not that you pushed your personal vision
> without any technical basis.

I have a different memory.  While I am also satisfied with the outcome, 
I remember that it was hard to explain why you couldn't just drop 
-fms-bitfields, and what analysis was required before you did that.  And 
the outcome was positive mostly (or only) because *I* did the analysis 
that was necessary to ensure there would be no regressions with *your* 
proposed patch.

What Daniel is asking is even less - he's only asking to *remove* the 
bits that symlink qemu-system-arm and qemu-system-riscv64 into 
qemu-system.  (Perhaps you could do that with a configure option 
instead, btw, that's also a possibility and would make CI integration 
easier).
>> This project was extremely complex and some disagreements are normal,
>> but overall I would say it has received support from the community for
>> years. It is close to the finish line, let's not forget all the
>> collaboration so far.
> 
> At this point, I don't see the finish line coming anytime soon.
> We are stuck in a situation where we now might have to design a whole
> new command line from scratch, for a reason I ignore.

This is simply not true. The important part: "We don't have to do all 
that straightaway. If we declare qemu-system 'experimental' initially we 
can iterate on that intentionally breaking compat in releases, without 
any impact on qemu-system-$TARGET".

Experimental doesn't mean unusable.
> - let's go with original plan, and just introduce -target option and
> call it a day for now. CLI refactoring can be initiated in parallel.

That's exactly what Daniel suggested.  In fact the same is true for more 
things than just the command line:

- filtering can be applied (if needed at all) to qemu-system *after* the 
binary is available in qemu.git, exactly because qemu-system is 
experimental;

- if we decide later that -target is not always needed, that would also 
be doable after the merge.

I hope this helps not so much solving the technical disagreement, but 
clarifying that yes, sometimes you've got to "agree to disagree", but 
personal attacks of any intensity are not "agreeing to disagree".

Paolo



^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
  2026-09-04 12:47             ` Paolo Bonzini
@ 2026-09-14  5:46               ` Pierrick Bouvier
  0 siblings, 0 replies; 57+ messages in thread
From: Pierrick Bouvier @ 2026-09-14  5:46 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Daniel P. Berrangé, Yonggang Luo, qemu-devel, Xianglai Li,
	Alistair Francis, Chinmay Rath, Sunil V L, qemu-riscv,
	Alexander Bulekov, Zhao Liu, Eric Farman, Laurent Vivier,
	Peter Maydell, Chao Liu, Liu Zhiwei, Palmer Dabbelt, Song Gao,
	Harsh Prateek Bora, Glenn Miles, Daniel Henrique Barboza,
	qemu-s390x, Jiaxun Yang, Philippe Mathieu-Daudé,
	Michael S. Tsirkin, Stefan Hajnoczi, Alex Bennée,
	David Hildenbrand, qemu-ppc, qemu-arm, Igor Mammedov,
	Aleksandar Rikalo, Nicholas Piggin, Cornelia Huck,
	Richard Henderson, Ilya Leoshkevich, Fabiano Rosas,
	Aurelien Jarno, Ani Sinha, Bibo Mao, Marc-André Lureau,
	Matthew Rosato, Weiwei Li, Darren Kenny

On 9/4/26 5:47 AM, Paolo Bonzini wrote:
> On 8/27/26 21:58, Pierrick Bouvier wrote:
>> On 8/27/2026 10:48 AM, Paolo Bonzini wrote:
>>> Whoa whoa.
>>>
>>
>> I apologize to Daniel, and other people on this thread for resorting to
>> sarcasm in this situation, and personally mention Daniel in my answer.
>>
>> It stems from the fact that it's not the first time Daniel come on a
>> thread to push a view (that might be wrong) and don't listen to other's
>> people opinion, or leave the conversation when he has no more arguments
>> or discover he's wrong. I'm not the first one to discover this, and it's
>> a topic that came from multiple people I met. I invite anyone to tell me
>> publicly it's in my head, and that it is wrong.
> 
> Please stop.  Just stop.  "It came from multiple people" never ends well.
> 
> I have my own disagreements with Daniel, which is no surprise since I've
> known him at work for over 15 years.  In fact, we probably had a couple
> just this week, though that's fortunately above average.  We have
> different personalities, we come from different cultural backgrounds.
> We are still able to respect each other and I seek his opinion even if
> (or sometimes because) I know it'll be different and make things harder
> for me. :)
> 
>>> Sometimes people don't reply not because they disagree, but because
>>> they trust the people involved to resolve the problem.
>>
>> We presented a plan a year ago, for which multiple people have been
>> supportive in general. Now we are close to having a single binary
>> upstream, we have Daniel coming last minute and asking to solve issues
>> we are not at yet. I feel it's not helping us, and simply blocking work.
>>
>> Daniel's main concern (correct me if I'm wrong), is that we might
>> introduce regressions by introducing a -target option, and filtering on
>> QOM types.
> 
> I'll briefly touch the technical part.  As it was explained, the problem
> is really just in the use of symlinks for aarch64 and riscv64 binaries.
> 
> All that Daniel is *asking for* is to split the experimental part from
> the existing one.  Did he go on a tangent on what else he'd like from
> the experimental part?  Yes, but that's simply a justification for why
> it's better to keep it split.
> 
>> I have no problem with anyone deciding to refactor the QEMU command
>> line, but it's a different problem from what we are doing now.
>> We just want to provide a first version upstream mixing at least two
>> base architectures, and providing exact same behavior than existing
>> binaries.
> 
> Yes, and that's fine.
> 
>>> Let me remind you of the discussion we had about -fms-bitfields and
>>> how it was resolved amicably and profitably.
>>
>> I really appreciated this exchange with you. Even if I was a newcomer,
>> you explained where you disagreed, but accepted a different answer. Then
>> we iterated to prove that existing struct layout were not impacted, and
>> we both observed it was safe to remove this option. I felt like we both
>> worked toward a goal, and not that you pushed your personal vision
>> without any technical basis.
> 
> I have a different memory.  While I am also satisfied with the outcome,
> I remember that it was hard to explain why you couldn't just drop
> -fms-bitfields, and what analysis was required before you did that.  And
> the outcome was positive mostly (or only) because *I* did the analysis
> that was necessary to ensure there would be no regressions with *your*
> proposed patch.
> 
> What Daniel is asking is even less - he's only asking to *remove* the
> bits that symlink qemu-system-arm and qemu-system-riscv64 into
> qemu-system.  (Perhaps you could do that with a configure option
> instead, btw, that's also a possibility and would make CI integration
> easier).
>>> This project was extremely complex and some disagreements are normal,
>>> but overall I would say it has received support from the community for
>>> years. It is close to the finish line, let's not forget all the
>>> collaboration so far.
>>
>> At this point, I don't see the finish line coming anytime soon.
>> We are stuck in a situation where we now might have to design a whole
>> new command line from scratch, for a reason I ignore.
> 
> This is simply not true. The important part: "We don't have to do all
> that straightaway. If we declare qemu-system 'experimental' initially we
> can iterate on that intentionally breaking compat in releases, without
> any impact on qemu-system-$TARGET".
> 
> Experimental doesn't mean unusable.
>> - let's go with original plan, and just introduce -target option and
>> call it a day for now. CLI refactoring can be initiated in parallel.
> 
> That's exactly what Daniel suggested.  In fact the same is true for more
> things than just the command line:
> 
> - filtering can be applied (if needed at all) to qemu-system *after* the
> binary is available in qemu.git, exactly because qemu-system is
> experimental;
> 
> - if we decide later that -target is not always needed, that would also
> be doable after the merge.
> 
> I hope this helps not so much solving the technical disagreement, but
> clarifying that yes, sometimes you've got to "agree to disagree", but
> personal attacks of any intensity are not "agreeing to disagree".
>

Thanks for the answer Paolo, I took note of all the points you mentioned.

Regarding the future direction, I would be happy to see an 
"experimental" binary, without any symlink set for now. Beyond filtering 
we can implement or not, my understanding was that people involved were 
not in favor to see -target option.

A solution we could have is indeed to expose all machines/cpus/devices 
(knowing it will very quickly create more problems with QOM types having 
duplicated names - riscv64 vs aarch64), and let user pick any 
combination. However, we still need a -target option to set the correct 
TargetInfo internally, independently of all the rest.

I'll let someone else do a proposal on the topic as I spent a lot of 
energy on this with a specific direction (option + filtering) without 
reaching consensus, and I'll be happy to follow any direction that will 
be accepted by the community.

> Paolo
> 

Thanks,
Pierrick


^ permalink raw reply	[flat|nested] 57+ messages in thread

end of thread, other threads:[~2026-09-14  5:47 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-23 15:07 [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system Yonggang Luo
2026-08-23 15:07 ` [PATCH 01/12] accel: use a shared TYPE_ACCEL_CPU parent Yonggang Luo
2026-08-23 15:07 ` [PATCH 02/12] hw/riscv/virt: use unique QOM name and target filter Yonggang Luo
2026-08-23 15:07 ` [PATCH 03/12] hw/arm/virt: " Yonggang Luo
2026-08-26 12:49   ` Daniel P. Berrangé
2026-08-23 15:07 ` [PATCH 04/12] hw/arm/virt: prefix ACPI helpers with arm_virt_ Yonggang Luo
2026-08-24  7:18   ` Philippe Mathieu-Daudé
2026-08-23 15:07 ` [PATCH 05/12] hw/riscv/virt: prefix ACPI helpers with riscv_virt_ Yonggang Luo
2026-08-24  7:19   ` Philippe Mathieu-Daudé
2026-08-23 15:07 ` [PATCH 06/12] hw/loongarch/virt: prefix ACPI helper with loongarch_virt_ Yonggang Luo
2026-08-24  1:00   ` gaosong
2026-08-24  7:20   ` Philippe Mathieu-Daudé
2026-08-23 15:07 ` [PATCH 07/12] target/riscv: uniquify TCG crc32, crc32c, and wfi helper names Yonggang Luo
2026-08-24  7:22   ` Philippe Mathieu-Daudé
2026-08-23 15:07 ` [PATCH 08/12] target/riscv: seed cfg.big_endian from TargetInfo Yonggang Luo
2026-08-26 18:37   ` Philippe Mathieu-Daudé
2026-08-23 15:07 ` [PATCH 09/12] target-info: register le and be TargetInfo variants Yonggang Luo
2026-08-24 16:22   ` Pierrick Bouvier
2026-08-24 19:01     ` Yonggang Luo
2026-08-26 18:41       ` Philippe Mathieu-Daudé
2026-08-23 15:07 ` [PATCH 10/12] target-info: add -target and program-name selection Yonggang Luo
2026-08-24 16:24   ` Pierrick Bouvier
2026-08-26 12:46   ` Daniel P. Berrangé
2026-08-26 18:13     ` Pierrick Bouvier
2026-08-27 10:13       ` Daniel P. Berrangé
2026-08-27 12:25     ` Daniel P. Berrangé
2026-08-23 15:07 ` [PATCH 11/12] target-info: dispatch CPU QMP, dump, and Angel semihosting Yonggang Luo
2026-08-23 15:07 ` [PATCH 12/12] meson: link ARM and RISC-V into qemu-system Yonggang Luo
2026-08-24 16:20   ` Pierrick Bouvier
2026-08-24 19:04     ` Yonggang Luo
2026-08-26 13:00     ` Daniel P. Berrangé
2026-08-26 17:40       ` Pierrick Bouvier
2026-08-26 18:05         ` Philippe Mathieu-Daudé
2026-08-26 18:08           ` Yonggang Luo
2026-08-24 16:36 ` [PATCH 00/12] single-binary: " Pierrick Bouvier
2026-08-25 15:42 ` Daniel P. Berrangé
2026-08-25 16:55   ` Yonggang Luo
2026-08-25 17:22     ` Daniel P. Berrangé
2026-08-25 17:11   ` Yonggang Luo
2026-08-26 12:32 ` Daniel P. Berrangé
2026-08-26 13:40   ` Mark Cave-Ayland
2026-08-26 13:58     ` Daniel P. Berrangé
2026-08-26 14:50     ` Yonggang Luo
2026-08-26 20:41     ` Daniel Henrique Barboza
2026-08-27  9:58       ` Daniel P. Berrangé
2026-08-26 18:35   ` Pierrick Bouvier
2026-08-26 18:53     ` Pierrick Bouvier
2026-08-27  9:44     ` Daniel P. Berrangé
2026-08-27 16:32       ` Pierrick Bouvier
2026-08-27 17:42         ` Peter Maydell
2026-08-27 17:48         ` Paolo Bonzini
2026-08-27 19:58           ` Pierrick Bouvier
2026-09-04 12:47             ` Paolo Bonzini
2026-09-14  5:46               ` Pierrick Bouvier
2026-08-27 10:22     ` Daniel P. Berrangé
2026-08-27 17:59   ` Paolo Bonzini
2026-08-28  5:44     ` Yonggang Luo

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.