All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chao Liu <chao.liu@processmission.com>
To: Yonggang Luo <luoyonggang@gmail.com>
Cc: qemu-level <qemu-devel@nongnu.org>,
	 Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>,
	"Daniel P. Berrange" <berrange@redhat.com>,
	 Paolo Bonzini <pbonzini@redhat.com>,
	Peter Maydell <peter.maydell@linaro.org>,
	 Markus Armbruster <armbru@redhat.com>,
	Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>,
	 Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Subject: Re: [RFC] single-binary: merge experimental qemu-system before filtering
Date: Fri, 28 Aug 2026 16:54:47 +0800	[thread overview]
Message-ID: <apFIRPwekx4tmAi9@ChaodeMacBook-Pro.local> (raw)
In-Reply-To: <CAE2XoE_-ewv3iC_MZ2sM1eKG=CUKM7MZa-ppJV0Vk1rE1h+19w@mail.gmail.com>

On Fri, Aug 28, 2026 at 03:44:43PM +0800, Yonggang Luo wrote:
> Hi,
> 
> This is a design RFC, not a patch series. It follows review of
> 
>   [PATCH 00/12] single-binary: link ARM and RISC-V into qemu-system
>   https://patchew.org/QEMU/20260823150731.896-1-luoyonggang@gmail.com/
> 
>   [PATCH v2 00/13] single-binary: link ARM and RISC-V into qemu-system
>   https://patchew.org/QEMU/20260826184229.1145-1-luoyonggang@gmail.com/
> 
> and Daniel P. Berrange's measurements of that v1.
> 
> What v2 already did
> ===================
> 
> v2 of that series already takes the v1 review that got maintainer
> support:
> 
> - Keep real qemu-system-$TARGET (and $TARGETw on Windows). v1
>   installed per-arch names as symlinks to qemu-system; v2 does
>   not. qemu-system is an extra binary from the ARM+RISC-V union,
>   behind a meson option.
> - argv[0] still selects the target for qemu-system-aarch64.
> - Drop v1 little- and big-endian TargetInfo variants
>   (target-info-<name>-le/be, -target aarch64-le). One TargetInfo
>   per target_name. Endian variants are later work.
> - -target ? lists target_name only. Unknown names point at
>   -target ? rather than printing the list and exit(1).
> - Do not build qemu-systemw for the combined binary, so Windows
>   data exports (qdev_prop_array / qdev_prop_*) do not block
>   enabling modules later.
> - TargetCpuOps (b444b4fb) for QMP CPU queries, dump, and ARM/RISC-V
>   semihosting, still as one process-wide table filtered at
>   register time. This RFC revises that into a map.
> 
> v2 still required -target on bare qemu-system, still used
> TYPE_TARGET_SPECIFIC on the combined binary, and did not mark
> qemu-system experimental. Those are what this RFC asks to freeze
> before posting the next series: extra binary stays, filtering is
> not a gate, proposal A vs B. Heterogeneous (no target: on -M)
> stays an error until later.
> 
> Why this RFC now
> ================
> 
> We are very close to a linked qemu-system that contains more than
> one target (ARM + RISC-V; see v2 above). v2 already dropped the
> symlink. The remaining delay is not "can it link", it is unresolved
> product questions: -target vs -M only, complete filtering before
> the first binary exists, experimental union vs looking like
> $TARGET.
> 
> This RFC is to freeze those questions so the next series can land
> an experimental qemu-system quickly, instead of another patch bomb
> that still debates the end result. Filtering, heterogeneous
> machines, modules for RSS, and CLI polish can follow against a
> real binary. Please comment on the split and on proposal A vs B;
> that is what unblocks the merge.
> 
> Thesis
> ======
> 
> Land an extra, experimental qemu-system first, without completing
> target/device filtering. Use that binary as the test vehicle for
> filtering. Keep today's qemu-system-$TARGET as real binaries, not
> symlinks.
> 
> qemu.git has no combined qemu-system today. Filtering, uniquify,
> and CPU-op dispatch are therefore untested assumptions. Completing
> TYPE_TARGET_SPECIFIC against qemu-system-riscv64 (a single-target
> link) does not prove the union case. We need a real qemu-system in
> the tree before filtering can be designed against measured
> behavior.
> 
> Berrange compared a v1 qemu-system-riscv64 *symlink* to today's
> standalone binary:
> 
> - qom-list-types went from about 770 classes to about 1530 (ARM
>   types leak into RISC-V)
> - -device help grew
> - RSS for -nodefaults -display none -M none went from 17.3 MB to
>   20.7 MB
> - A full-union guess was much worse for RISC-V
> 
> That is a packaging blocker if $TARGET becomes a symlink. Extra RAM
> on a *new* experimental qemu-system is acceptable if we document
> that this binary exposes the union. It is also not the last word
> on RSS.
> 
> Once modules are always enabled for qemu-system, unused machines
> and devices can live in .so / .dll / .dylib and stay out of the
> startup working set. One simple shape is one module per target, so
> qemu-system -M arm:virt (or -target aarch64) loads the ARM module
> and does not map RISC-V boards. That is later work, not a blocker
> for the first extra binary (Mark Cave-Ayland already suggested
> mandatory modules for qemu-system; Berrange did not want to block
> on that). The first merge still links the union into one
> executable so we have something to test.
> 
> This split is meant to take both review positions at the layer they
> apply to:
> 
> - Berrange / Paolo: do not replace qemu-system-$TARGET with a
>   symlink. A new qemu-system can be its own thing.
> - Pierrick: select TargetInfo when the user wants a single-target
>   view; TYPE_TARGET_SPECIFIC as the filtering mechanism. Matching
>   $TARGET introspection is the *goal* of a later filtering series,
>   not a gate on the first link.
> 
> Two CLI proposals for how to select one TargetInfo are below.
> They share argv[0] and -M target:machine. They differ on whether
> -target exists. A run with no selected TargetInfo (heterogeneous /
> SYS_EMU_TARGET_HETEROGENEOUS) is deferred: the first series only
> prints an error.
> 
> experimental-qemu-system
> ========================
> 
> Keep building real qemu-system-$TARGET as today (and $TARGETw on
> Windows). Add qemu-system alongside them, from the union of ARM and
> RISC-V for the first pair, behind a meson option, marked
> experimental.
> 
> Do not install per-arch names as symlinks to qemu-system. Distro
> packaging of qemu-system-riscv64 stays on the old RSS and QOM list.
> 
> The combined binary is documented as exposing everything that was
> linked. Incomplete device filtering is an accepted experimental
> defect, not a release blocker for this first binary. -M help /
> -device help with no selected TargetInfo may still list the union.
> Starting a machine that way is not supported yet (error; see
> below).
> 
> Binding TargetInfo
> ==================
> 
> A combined process has more than one TargetInfo (target_name, page
> bits, long width, CPU_RESOLVING_TYPE, endianness).
> 
> In this mail, single-target means the process has one selected
> TargetInfo / SysEmuTarget, like qemu-system-$TARGET today.
> Heterogeneous would mean it does not (SYS_EMU_TARGET_HETEROGENEOUS).
> That mode is not implemented yet.
> 
> Single-target runs still pick one TargetInfo before the chosen
> machine and accelerators initialize.
> 
> Shared in both proposals:
> 
> - argv[0]: qemu-system-aarch64 infers aarch64. Existing $TARGET
>   command lines stay valid. Single-target. -M virt works as today.
> - -M arm:virt on bare qemu-system: single-target. The target:
>   prefix selects TargetInfo arm and machine virt together. The
>   token is target_name (arm, aarch64, riscv32, riscv64).
>   Properties stay after the machine name:
>   -M aarch64:virt,gic-version=3.
> - Bare qemu-system and -M has no target: prefix: not supported
>   yet. Fail with an error that this would be a heterogeneous
>   machine (SYS_EMU_TARGET_HETEROGENEOUS), which is deferred, and
>   point at -M arm:virt and (proposal A) -target. Do not start
>   the VM. -M help / -device help with no selected TargetInfo may
>   still list the union so users can pick a qualified name.
> 
> If argv[0] and a target: prefix are both given, they must match.
> Unknown prefix names fail. -M help may also print qualified names
> (arm:virt, riscv64:virt) so users can opt into a single-target run.
> 
> Proposal A: -target plus -M target:machine
> ------------------------------------------
> 
> Pierrick suggested -target. Keep it as an optional way to select
> TargetInfo on the combined binary. It is not mandatory on
> qemu-system.
> 
> - -target aarch64: single-target. Later filtering can make this
>   look like qemu-system-aarch64. -M virt works as today.
> - If both -target and a target: prefix are given, they must match.
>   Unknown -target names fail and point at -target ?.
> 
>   qemu-system -M help
>   qemu-system -M virt              # error: heterogeneous not supported
>   qemu-system -M arm:virt ...
>   qemu-system -target aarch64 -M virt ...
>   qemu-system-riscv64 -M virt ...
> 
> Proposal B: target only in -M or argv[0] (alternative)
> -----------------------------------------------------
> 
> Do not add -target. The target is always embedded in the machine
> argument, or inferred from argv[0].
> 
> - qemu-system-aarch64 -M virt: single-target from argv[0].
> - qemu-system -M arm:virt: single-target from -M.
> - qemu-system -M virt: error (heterogeneous not supported yet).
> 
> There is no global option that selects TargetInfo before -M.
> Early option parsing still has to read -M (and argv[0]) before
> machines initialize, the same as proposal A reads -target.
> 
>   qemu-system -M help
>   qemu-system -M virt              # error: heterogeneous not supported
>   qemu-system -M arm:virt ...
>   qemu-system -M aarch64:virt,gic-version=3 ...
>   qemu-system-riscv64 -M virt ...

> 
> Compared with A: one place to write the target on the combined
> binary (-M), no new flag, no -target vs -M mismatch cases. The
> cost is that qemu-system -M virt is never a hidden alias for
> aarch64; colliding names must be qualified, and a single-target
> view of the union binary is qemu-system -M aarch64:virt, not
> qemu-system -target aarch64 -M virt.
> 
> Please pick A or B; the rest of this RFC is the same either way.
> 
I think Proposal B is clearer and easier to merge upstream. It does
not add another option, and the <target>: prefix in -M can select
the right TargetInfo.

We only need to check that -M <target>:<machine-name> is valid.
We do not need to rename existing machine names: parse the prefix
first, then keep the existing -M parser for the rest.

Another point to discuss is what should happen when -M is missing.
For the bare qemu-system, it should exit with an error instead
of choosing a default machine, because the target is unclear.

BTW, I haven't looked closely at the earlier patch series,
so I'm not sure how much this would affect the follow-up work.

Just my two cents.

Thanks,
Chao
> SYS_EMU_TARGET_HETEROGENEOUS (deferred)
> --------------------------------------
> 
> QAPI SysEmuTarget today is the configure list (aarch64, arm,
> riscv64, ...). A later process with no selected TargetInfo and no
> target: on -M would need a value that is not a single linked
> target: add heterogeneous (C name SYS_EMU_TARGET_HETEROGENEOUS).
> It would be a process mode, not a ./configure target and not
> qemu-system-heterogeneous.
> 
> The first series does not add that enum and does not run that
> mode. qemu-system -M virt with no argv[0] target and no -target
> fails with an error: heterogeneous machines are not supported
> yet; use -M arm:virt (and -target in proposal A). How such a
> machine would name per-CPU / per-device targets is later work.
> 
> target-info-def.c
> =================
> 
> The minimum compile unit for several targets in one process is
> target-info-def.c built once per target (COMPILING_PER_TARGET).
> Each translation unit registers one TargetInfo and a
> TYPE_TARGET_INFO QOM class. meson already does that for
> qemu-system-$TARGET. Combined qemu-system extracts those objects
> from every participating target, plus arch objects from a primary
> per base architecture (aarch64 and riscv64 for the first pair).
> 
> That is enough to have several TargetInfo values. Selecting one
> TargetInfo (-M arm:virt, argv[0], and -target in proposal A) picks
> one value for the run. With none of those, the first series errors
> out; it does not invent SYS_EMU_TARGET_HETEROGENEOUS. That is not
> enough to look like a single-target binary. That is the point of
> the first merge.
> 
> TYPE_TARGET_SPECIFIC
> ====================
> 
> Pierrick's series "single-binary: implement dynamic filtering for
> machine types" is a prerequisite and is already upstream. For a
> usable combined binary we need it at least for machines: without
> is_available(), -M virt in a union link is ambiguous or can start
> the wrong board against the selected TargetInfo.
> 
> Help and introspection depend on whether TargetInfo is already
> selected:
> 
> - No selected TargetInfo and no target: on -M: -M help /
>   -device help may list the union (qualified names). Starting a
>   machine is an error (heterogeneous not supported yet).
> - Selected TargetInfo (argv[0], -M arm:virt, or -target in
>   proposal A): filter with is_available() as today. -M virt is
>   unambiguous once TargetInfo is selected.
> 
> We do not need to finish filtering every QOM class before the first
> qemu-system exists. Machine-level TYPE_TARGET_SPECIFIC (already
> wired for ARM and RISC-V boards) is enough to select a board after
> TargetInfo is selected. Device and class leakage with -target is what
> Berrange measured; on experimental qemu-system that is accepted
> until filtering-against-qemu-system. Without a selected TargetInfo
> and without a target: prefix on -M, do not run; error.
> 
> New TYPE_TARGET_SPECIFIC annotations in the first series should be
> limited to what the combined link needs. Not a campaign to tag
> every class.
> 
> TargetCpuOps must be a map
> ==========================
> 
> A combined link cannot keep one global C symbol per architecture
> for query-cpu-definitions, dump notes, or Angel semihosting.
> Commit b444b4fb6ecb ("target-info: dispatch CPU QMP, dump, and
> arm/riscv semihosting") moved those handlers onto TargetCpuOps and
> TARGET_INFO_CPU_OP (one member at a time, type_init). That
> direction is required.
> 
> The implementation is not complete. It uses a single process-wide
> 
>   static TargetCpuOps target_cpu_ops;
> 
> and target_info_register_cpu_op() stores a member only when
> cpu_type matches the already selected TargetInfo. Other
> architectures are dropped. That depends on MODULE_INIT_QOM running
> after target_info_qom_set_target(). It is the same class of
> assumption we cannot test until a combined binary exists, and it
> is the wrong shape even for qemu-system-*: one global filled or
> ignored by init order, instead of a table keyed by the selected
> target.
> 
> Proposal: keep TARGET_INFO_CPU_OP. Replace the single global with
> a map from the selected target to its TargetCpuOps. Lookup uses
> target_arch() (SysEmuTarget):
> 
>   target_info_cpu_ops() -> &map[target_arch()]
> 
> Registration always fills that architecture's slot. It does not
> compare against the currently selected TargetInfo and drop the
> rest.
> 
> qemu-system-aarch64 has one occupied slot. qemu-system has one
> slot per linked target. Same API, same callers in hw/core and
> semihosting. Help paths with no selected TargetInfo
> (qemu-system -M help) list the union and must not dispatch CPU
> QMP / dump / semihosting through a single-arch ops table. A VM
> start still needs argv[0], -M arm:virt, or -target (proposal A).
> There is no map[SYS_EMU_TARGET_HETEROGENEOUS] until that mode
> exists.
> 
> CPU_RESOLVING_TYPE is not a unique map key. TYPE_ARM_CPU is shared
> by arm and aarch64, TYPE_RISCV_CPU by riscv32 and riscv64,
> TYPE_X86_CPU by i386 and x86_64. Those siblings share one object
> file in the combined link (the primary softmmu target).
> Registration fills the compiling TARGET_ARCH, then aliases the
> same TargetCpuOps to other SysEmuTarget values whose
> TargetInfo.cpu_type matches. Lookup is still map[target_arch()].
> 
> What the first series is not
> ============================
> 
> - Completing Kconfig / target / device filtering
> - Implementing a heterogeneous machine. First series: error only.
>   SYS_EMU_TARGET_HETEROGENEOUS and how it names per-CPU /
>   per-device targets come later.
> - Mandatory modules / splitting machines and devices (or a whole
>   target) into .so / .dll / .dylib. That is the RSS follow-up
>   once qemu-system exists, not a gate on linking it.
> - A new experimental CLI (-nodefaults default, no default machine,
>   dropping -hda / -drive, ordered args)
> - Replacing qemu-system-$TARGET with a symlink
> 
> Symbol uniquify (QOM names, helpers, TYPE_ACCEL_CPU) remains
> necessary to *link*. That is engineering, not a change in user
> semantics.
> 
> filtering-against-qemu-system
> =============================
> 
> Once qemu-system exists in the tree, filtering can be implemented
> and tested for real:
> 
>   qemu-system -M riscv64:virt ...
>   qemu-system -target riscv64 ...   # proposal A only
>   qemu-system-riscv64 ...
> 
> That is the series that should drive qom-list-types, -device help,
> and RSS toward the single-target numbers Berrange measured, for
> the single-target path. Modules (always on for qemu-system, unused
> targets not mapped) are the other RSS tool, after the binary
> exists. Distros keep shipping qemu-system-$TARGET until they opt
> into the combined binary.
> 
> The no-selected-TargetInfo path is an error until heterogeneous
> support exists. Filtering must not make qemu-system -M help hide
> other arches.
> 
> Please comment on this split, and on proposal A vs B. We are
> close enough that a decision here is what lets the next series
> land experimental qemu-system instead of waiting on filtering.
> 
> --
>          此致
> 礼
> 罗勇刚
> Yours
>     sincerely,
> Yonggang Luo


  reply	other threads:[~2026-08-28  8:55 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-28  7:44 [RFC] single-binary: merge experimental qemu-system before filtering Yonggang Luo
2026-08-28  8:54 ` Chao Liu [this message]
2026-08-28  9:57 ` Philippe Mathieu-Daudé
2026-08-28 10:21   ` Yonggang Luo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=apFIRPwekx4tmAi9@ChaodeMacBook-Pro.local \
    --to=chao.liu@processmission.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=daniel.barboza@oss.qualcomm.com \
    --cc=luoyonggang@gmail.com \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=pierrick.bouvier@oss.qualcomm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.