curr_cflags() is called once per TB dispatch, from helper_lookup_tb_ptr()
and from the cpu_exec() loop. It recomputes the same value every time:
uint32_t cflags = cpu->tcg_cflags;
if (unlikely(cpu_single_stepping(cpu))) { ... }
else if (qatomic_read(&one_insn_per_tb)) { ... }
else if (qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) { ... }
That is three loads and three branches on the hottest path in the
interpreter, for state that changes only when gdb enables single-step,
when one-insn-per-tb is toggled, or when the log mask changes.
None of the three has to be sampled at dispatch time. Fold each into
CPUState::tcg_cflags where it changes and curr_cflags() becomes a single
load of a field that TB lookup has to read anyway.
The derived bits -- CF_COUNT_MASK, CF_NO_GOTO_TB, CF_NO_GOTO_PTR and
CF_SINGLE_STEP -- are never set by tcg_cflags_set(), so tcg_update_cflags()
can recompute them in place without disturbing the rest, and conversely
tcg_cflags_set() ORs in its bits without disturbing them.
There are three places to call it:
- tcg_exec_realizefn(), so that a CPU created after the command line has
been parsed starts out with the right value. This covers user-only,
where tcg_cpu_init_cflags() is not reached. linux-user's cpu_copy()
copies tcg_cflags wholesale, so a cloned thread inherits it.
- cpu_single_step(), which changes one CPU. gdb is the only caller that
matters; in system mode it runs with the vCPUs stopped, and in user mode
gdb_continue_partial() can reach a thread that is still running, because
gdb_handlesig() stops only the thread that trapped. That is exactly the
plain cross-thread store to another CPU's CPUState that
cpu->singlestep_flags already was, read back by that CPU through
cpu_single_stepping() in curr_cflags(). This patch changes which field
carries it, not who writes it or how.
- hmp_one_insn_per_tb() and hmp_log(), which change every CPU while the
vCPUs are running, so the update is queued with async_run_on_cpu() and
each CPU writes its own cflags from its own thread. The command line
spellings of those two settings need nothing: they are parsed before
any CPU is realized, so tcg_exec_realizefn() picks them up.
Measured with qemu-alpha running an emulated alpha gcc 16.2.0 compiling
the SQLite 3.45.1 amalgamation (255k lines, -O2) on an x86-64 host, in a
build configured with --enable-lto:
before: 1,646,994,254,249 instructions
after: 1,562,204,796,597 instructions -5.15%
That workload issues 8.4 billion dispatches, so the per-call saving is
small but the aggregate is not. The emulated compiler produces
byte-identical output before and after.
Wall clock does not move: 133.19s to 132.58s, a 0.46% difference against a
run-to-run spread larger than that. The removed work is a few predictable
loads and branches that the host executes largely in parallel with the
surrounding dispatch, so this patch is worth taking for the instruction
count and for what it enables, not for a time saving that can be measured
on its own.
v4: Update the cflags from the HMP handlers for 'log' and 'one-insn-per-tb'
rather than from qemu_set_log_internal() and the accelerator property
setter. Those are the paths that reach a running vCPU, and the monitor
is the only thing that does. Suggested by Richard Henderson.
v4: Queue the per-CPU update with async_run_on_cpu() rather than
async_safe_run_on_cpu(). Halting the other vCPUs buys nothing: the
queued work already runs on the owning CPU's own thread. Suggested by
Alex Bennee, who also asked whether there are cross-vCPU updates of
tcg_cflags at all. With this change the monitor path has none: the
only remaining writer from another thread is cpu_single_step(), above,
which is neither new nor made worse here.
v4: Move the stub to accel/stubs/, which is where the other accelerator
stubs live.
Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260901034808.3524945-2-mattst88@gmail.com>
Guard SysemuCPUOps::monitor_defs field and the per-target MonitorDef
arrays with CONFIG_HMP. These tables are only used by HMP 'print' and
'info registers' commands.
Note that the #ifdef in hmp.c is not optimal, but will be removed
later once the unit is built conditionally.
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20260828-qemu-no-hmp-v5-42-9227de146347@redhat.com>
Add #ifdef CONFIG_HMP around all hmp_* function implementations and
their HMP-only helpers across subsystems.
This covers monitor_register_hmp* callers, hmp_info_* handlers, and
HMP-only helper functions like slirp_lookup.
To link succesfully, use empty cmds tables in hmp-cmds.c (to be removed
once meson build-sys is updated with !hmp support later in the series)
Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20260828-qemu-no-hmp-v5-41-9227de146347@redhat.com>
Rename monitor_printf->monitor_hmp_printf, monitor_vprintf->
monitor_hmp_vprintf, and monitor_printc->monitor_hmp_printc, changing
the first parameter from Monitor * to MonitorHMP * to enforce type
safety. The implementation is also simplified: monitor_hmp_vprintf now
directly calls g_strdup_vprintf + monitor_puts, removing the virtual
dispatch via moncls->vprintf.
The dev_print() callbacks are temporarily using the MONITOR_HMP(mon)
cast, they are fixed in the following commits.
Early return in qemu_vprintf() if "hmp" is NULL, relying on
monitor_hmp_vprintf() handling NULL case is a bit uncommon.
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20260828-qemu-no-hmp-v5-37-9227de146347@redhat.com>
These functions access mon_cpu_path, which is a MonitorHMP-specific
field. Narrowing their signatures from Monitor* to MonitorHMP* makes the
type system enforce what was already true at runtime: every caller is in
an HMP context. The expression parser's MONITOR_HMP() casts are safe
because it is only reachable from handle_hmp_command(), they will be
dropped with later patches.
Reviewed-by: Dr. David Alan Gilbert <dave@treblig.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20260828-qemu-no-hmp-v5-36-9227de146347@redhat.com>
HMP commands are specific to the HMP monitor, so make the cmd function
pointer in HMPCommand take MonitorHMP * instead of Monitor *. This
strengthens type safety and makes the HMP-specific nature of these
handlers explicit.
Handler functions are renamed to take MonitorHMP *hmp, with a local
Monitor *mon = MONITOR(hmp) added where the body needs the base type.
Following patches will drop it, since most functions are HMP specific.
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>
Reviewed-by: Dr. David Alan Gilbert <dave@treblig.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20260828-qemu-no-hmp-v5-31-9227de146347@redhat.com>
"monitor/monitor.h" don't use anything declared in the generated
"qapi/qapi-emit-events.h" header.
However the "monitor/monitor-internal.h" do:
107 struct MonitorClass {
...
116 /*
117 * If non-NULL, the monitor is able to send event
118 * notifications back to the client
119 */
120 void (*emit_event)(Monitor *mon, QAPIEvent event, QDict *qdict);
^^^^^^^^^
Move the header inclusion to "monitor/monitor-internal.h" to
avoid including / re-exposing unnecessary declarations in the
global "monitor/monitor.h" header.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20260812211708.92824-11-philmd@oss.qualcomm.com>
Files in monitor/ use the QEMU_LOCK_GUARD() macros, which
are declared in "qemu/lockable.h". Include the latter to
avoid when refactoring unrelated headers:
../monitor/fds.c:146:5: error: call to undeclared function 'QEMU_LOCK_GUARD'
146 | QEMU_LOCK_GUARD(&mon->mon_lock);
| ^
../monitor/monitor.c:176:5: error: call to undeclared function 'QEMU_LOCK_GUARD'
176 | QEMU_LOCK_GUARD(&mon->mon_lock);
| ^
../monitor/qmp.c:164:5: error: call to undeclared function 'WITH_QEMU_LOCK_GUARD'
164 | WITH_QEMU_LOCK_GUARD(&mon->mon_lock) {
| ^
Fixes: 0210c3b39b ("monitor: Use LOCK_GUARD macros")
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20260812211708.92824-9-philmd@oss.qualcomm.com>
Both monitor.c and qmp.c use types / methods declared in
"qemu/aio-wait.h". Include the latter to avoid the following
errors when refactoring unrelated headers:
../monitor/monitor.c:648:5: error: call to undeclared function 'AIO_WAIT_WHILE_UNLOCKED'
648 | AIO_WAIT_WHILE_UNLOCKED(NULL,
| ^
../monitor/qmp.c:792:9: error: call to undeclared function 'aio_wait_bh_oneshot'
792 | aio_wait_bh_oneshot(iothread_get_aio_context(mon_iothread),
| ^
Fixes: 9ce44e2ce2 ("qmp: Move dispatcher to a coroutine")
Fixes: a5df506e12 ("monitor: implement support for deleting QMP objects")
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20260812211708.92824-8-philmd@oss.qualcomm.com>
The function calls qemu_coroutine_yield(), and is called from
monitor_qmp_dispatcher_co().
Fixes: 60f4f62efe ("monitor: extract request dequeuing to a new function")
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
The default monitor is usually a long lived object that will exist for
the entire lifetime of the VM. A monitor can only service a single
client at a time though, and so it might be desirable to hotplug
additional monitors at runtime for specific tasks. If doing that,
however, there is a need to remove the monitor when it is no longer
needed.
A use case for hotplugging a monitor can involve a user wishing to
spawn an ad hoc script that uses a temporary monitor. The script can
ask the management application to hotplug a monitor and pass back a
pre-opened FD using SCM_RIGHTS. In this case the lifetime of the
script is not tied to the management application and thus it is
desirable to have automatic cleanup when the script exits.
Allowing a client to run "object-del" against its own monitor adds
complex edge cases, as it would be desirable to send the QMP response
despite the monitor sending it being deleted. Doing "object-del" alone
will also result in orphaning a character device backend instance, as
there is no opportunity to run the companion "chardev-del" command.
A simpler way to ensure cleanup is to add the concept of auto-deleting
monitor objects. Specifically when the "CHR_EVENT_CLOSED" event is
emitted, the equivalent of "object-del" + "chardev-del" can be run
internally. Since the transient client has already droppped its
monitor connection, there is no synchronization to be concerned about
with sending QMP replies. There is still some internal synchronization
needed, however, between the character device event callback and the
bottom-half that runs the delete. There is a chance that an incoming
client connection may arise before the bottom-half runs, which has
to be checked. Once the monitor object is deleted, the event callback
is unregistered from the character device, eliminating any further
races before the character device is fully deleted.
This is implemented via a new "close-action=none|delete" property on
the 'monitor-qmp' object. This concept could be extended with further
actions in future, for example:
* close-action=shutdown - graceful guest shutdown
* close-action=terminate - immediate guest poweroff
* close-action=stop - pause guest CPUs while the monitor is not
connected to any client
This is left as an exercise for future interested contributors.
Tested-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20260706135824.2623960-33-berrange@redhat.com>
[Commit message typos fixed]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
The removal sequence is:
1. Remove from mon_list under monitor_lock. This must happen
before disconnecting chardev handlers to prevent event
broadcast from calling monitor_flush_locked() after the
gcontext reset, which would create an out_watch on the wrong
GMainContext (see monitor_cancel_out_watch()).
2. Cancel any pending out_watch while gcontext still points to the
correct context.
3. Disconnect chardev handlers, passing context=NULL and close
the connection.
4. Drain pending requests from any in-flight monitor_qmp_read().
5. Destroy the monitor object
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[DB: extracted from a larger commit and refactored to apply
to the new monitor class structure. Remove 'self delete'
feature which requires complex special-case code]
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20260706135824.2623960-28-berrange@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
The monitor_accept_input API is called from a bottom half, and will
invoke qemu_chr_fe_accept_input().
When a following patch introduces the ability to delete monitors, it
will be neccesary to delete the bottom half. Protecting the call to
qemu_chr_fe_accept_input with the monitor lock will allow for
synchronization with the deletion process.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[DB: extracted from a larger commit and refactored to apply
to the new monitor class structure]
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20260706135824.2623960-27-berrange@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
If an 'object_del' command for a QMP monitor arrives targetting the
current monitor, reject this request. If the current monitor is
deleted, it will be impossible to send any reply and the client won't
be able to remove the corresponding chardev backend.
Note, it is not possible to rely on checking monitor_cur() because
if 'object_del' is called via human-monitor-command, monitor_cur()
will reflect the temporary HMP, not the QMP target that needs to
be checked.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[DB: extracted monitor tracking from larger commit; added logic
to monitor_qmp_prepare_delete to reject request]
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20260706135824.2623960-26-berrange@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Convert monitor_accept_input from a oneshot BH (aio_bh_schedule_oneshot)
to a persistent BH (aio_bh_new + qemu_bh_schedule). Oneshot BHs cannot
be cancelled, so monitor_resume() racing with destruction would schedule
a callback against memory that monitor_qmp_destroy() is about to free.
A persistent BH can be deleted during destruction, cancelling any
pending schedule.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[DB: extracted oneshot BH conversion from larger commit]
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20260706135824.2623960-25-berrange@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Implement the user creatable QOM interface and define the monitor-qmp
and monitor-hmp types in QAPI. This unlocks the ability to create them
on the command line with -object or in HMP/QMP with object_add.
For example:
$QEMU -chardev stdio,id=monchr0 -object monitor-hmp,id=mon0,chrdev=monchr0
Initially the "prepare_delete" callback is hardcoded to return an error
which means -object and object_add can be used, but object_del will fail.
Support for deleting monitors will be introduced in subsequent commits.
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20260706135824.2623960-24-berrange@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
The monitor_is_hmp_non_interactive method is used by
monitor_suspend and monitor_resume, to make them a no-op
if the HMP does not use readline.
There are only a handful of callers of suspend/resume and
they can be made to skip the call when readline is not
present.
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20260706135824.2623960-23-berrange@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Start to take advantage of QOM, by using object init and finalize
methods to replace monitor_data_init and monitor_data_destroy.
A standalone helper is provided to enable the I/O thread for QMP
where appropriate for the chardev backend.
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20260706135824.2623960-12-berrange@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
The 'skip_flush' field is set on the dummy throwaway HMP monitor
object created by QMP's 'human-monitor-command', as an indication
not to try to write data to the chardev. Instead the QMP command
impl will grab the data straight out of the in-memory buffer.
The flag is redundant, however, as the monitor code could instead
simply check the 'fe_is_open' field on the CharFrontend, which
will be false in the same scenarios that 'skip_flush' is true.
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20260706135824.2623960-11-berrange@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Current the monitor_new_hmp/monitor_new_qmp constructors accept
a Chardev object pointer. To facilitate the next commit which will
introduce a QOM property for the character device ID, switch to
accepting an chardev ID in the constructor.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20260706135824.2623960-7-berrange@redhat.com>
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This introduces abstract QOM type "monitor", with concrete subtypes
"monitor-hmp" and "monitor-qmp". This is the bare minimum conversion
of just the type declarations and replacing g_new/g_free with
object_new/object_unref.
Command line option "-monitor" now creates a "monitor-hmp" object
"/objects/compat_monitorNNN" in addition to the character device
"/chardevs/compat_monitorNNN". NNN counts up from zero.
Exception: "-monitor chardev:ID" creates a "monitor-hmp" object
"/objects/ID", and does not create a character device.
"-qmp" and "-qmp-pretty" work the same, except they create a
"monitor-qmp" object.
"-mon" now creates either a "monitor-hmp" or "monitor-qmp" object
"/objects/ID" if the option argument provides an ID, else
"/objects/compat_monitorNNN".
"-gdbstub" and "-serial mon:..." now create a "monitor-hmp" object
"/objects/compat_monitorNNN".
Note that the object's name in "/objects/" matches the QemuOpts ID when
it exists. The only cases where it doesn't exist are "-mon" without ID,
"-gdbstub" and "-serial mon:".
A future patch will make "monitor-hmp" and "monitor-qmp" work with
"-object" and "object-add".
Note: there is a slight change in the NNN values assigned. The old
code would increment the counter for every monitor added (except for
-mon, -serial mon:..., -gdbstub), regardless of whether it needed a
"compat_monitorNNN" ID assignment. Now it is only incremented when an
automatic ID assigned is needed (but even for -mon, -serial mon:...,
-gdbstub).
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20260706135824.2623960-6-berrange@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Commit message made slightly more precise]
Signed-off-by: Markus Armbruster <armbru@redhat.com>