All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/49] Make HMP optional (and later standalone)
@ 2026-08-16 19:12 Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 01/49] vl: fix -monitor none prefix matching Marc-André Lureau
                   ` (48 more replies)
  0 siblings, 49 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Philippe Mathieu-Daudé, Philippe Mathieu-Daudé

Hi,

This series makes HMP compile-time optional via --disable-hmp. The
resulting binary speaks only QMP - reducing the attack surface, binary
size and enforcing a separation between machine-readable interface and
interactive debugging console.

QMP offers almost all the functionality HMP could provide, so a separate
standalone "HMP-like" console could be implemented on top of it. The
rough list of missing commands (+complexity estimation) after this
series:

Debugging / introspection:
- info registers (medium) - plus $reg expression handling
- x/xp read memory (medium)
- gpa2hpa/gpa2hva/gva2gpa address translation (medium)
- info lapic (high) - deep x86 APIC state, lots of registers
- info mem (high) - virtual memory mappings, different per arch
- info tlb (high) - virt-to-phys mappings, also per arch
- info mtree (high) - memory region tree, multiple view modes
- info skeys (medium) - s390x storage keys
- info cmma (medium) - s390x CMMA values
- info qdm (easy) - could probably be folded into QOM introspection
- info qtree (medium) - same, maybe QOM introspection is enough
- info snapshots (medium)
- info usbhost (medium)
- info via (medium) -- VIA south bridge state

Simple actions / settings:
- gdbserver (trivial)
- boot_set (easy)
- mce (easy) - x86 MCE injection
- sum (easy) - memory checksum
- sync-profile (easy) - enable/disable/reset
- info sync-profile (medium)
- one-insn-per-tb (easy) - could be a QOM property on the accelerator
- pcie_aer_inject_error (easy)
- migration_mode (medium?)
- i/o ioport read/write (easy)
- hostfwd-add/hostfwd-remove (medium) - slirp port forwarding
- log/logfile (medium)
- trace-file (medium)

Also, to let clients do disassembly on their side, it'd be useful to
have something like "query-disassemble-info" that gives the client what
architecture and endianness is used etc.

In the meantime, being able to build without HMP is valuable and helps
identifying the missing pieces. The series does so by steps:

- preparatory cleanups and bug fixes
- add commands without QMP equivalent and needed for tests
- convert most iotests and qtests from HMP to QMP
- guard HMP-only code paths
- make HMP source files conditional in the build system

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
Changes in v3:
- adapted to QOM refactoring of the Monitor subsystem, use type-system
  enforced MonitorHMP 
- adjusted hmp_snapshot_blkdev() code for non-optional filename
- dropped patch 39/40 "monitor: guard HMP internal helpers with CONFIG_HMP"
- guard new tests for HMP dependency
- rebase, minor fixups
- Link to v2: https://lore.kernel.org/qemu-devel/20260626-qemu-no-hmp-v2-0-8af31bc54c61@redhat.com

Changes in v2:
- add "target/i386: return an error for invalid CPU in hmp_mce()",
  suggested by Philippe
- drop all the patches converting iotests to QMP - instead skip
  when HMP is disabled. The series was getting significantly bigger with
  those, we can address the remaining conversion later.
- clean up the series to be fully bisectable
- rebased, add r-b trailers
- Link to v1: https://lore.kernel.org/qemu-devel/20260521-qemu-no-hmp-v1-0-d104f809e145@redhat.com

To: qemu-devel@nongnu.org
Cc: Philippe Mathieu-Daudé <philmd@mailo.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>

---
Marc-André Lureau (49):
      vl: fix -monitor none prefix matching
      hmp: remove 'vcpu' argument from trace-event help
      hmp: fix snapshot_blkdev argument type
      target/i386: decouple cpu_x86_inject_mce() from Monitor
      target/i386: return an error for invalid CPU in hmp_mce()
      system: move gpa2hva() to system memory unit
      system: decouple qmp_inject_nmi() from Monitor
      monitor: move HMP-only fields from Monitor to MonitorHMP
      tests/functional: use query-version QMP command instead of HMP
      net/qapi: add x-query-usernet command
      python, tests: switch usernet queries from HMP to QMP
      tests/qtest/pnv: drop unnecessary -serial mon:stdio
      tests/qtest/qmp-test: don't depend on human-monitor-command
      tests/qtest/numa-test: replace HMP "info numa" with QMP query-cpus-fast
      tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block
      tests/qtest/device-introspect-test: fix test without HMP
      tests/qemu-iotests/205: fix race in assertExportNotFound
      net: add x-query-network QMP command
      tests/qtest/netdev-socket: replace HMP with x-query-network QMP
      qemu-io: propagate errors through Error API instead of printf
      block: add x-qemu-io QMP command
      qtest: add qemu-io command to the qtest protocol
      qtest/ide-test: convert to use qtest qemu-io command
      tests/qemu-iotests: add qmp_qemu_io()
      tests/qemu-iotests: convert pause/resume_drive() to QMP
      build-sys: add 'hmp' option
      monitor: reject readline monitor when HMP is disabled
      system: guard HMP initialization paths with CONFIG_HMP
      tests: skip HMP-dependent tests when HMP is disabled
      monitor: isolate HMP declarations in hmp.h
      monitor: change HMPCommand cmd to take MonitorHMP
      monitor: make hmp_handle_error() take MonitorHMP
      monitor: add monitor_cur_hmp() helper
      qemu-print: switch to use monitor_cur_hmp()
      error-report: switch to use monitor_cur_hmp()
      monitor: tighten monitor_set_cpu()/get_cpu()
      monitor: tighten monitor_printf*()
      hexagon: make dump_mmu() take MonitorHMP
      qdev-monitor: make print_dev() callback take MonitorHMP
      qapi: make HMP-specific schema entries conditional on CONFIG_HMP
      Guard HMP command implementations with CONFIG_HMP
      target: guard MonitorDef tables with CONFIG_HMP
      hw: guard BusClass::print_dev with CONFIG_HMP
      hexagon: condition HMP-specific code
      build-sys: make HMP source files conditional on have_hmp
      stubs: split monitor-core stubs into separate compilation units
      monitor: move monitor_hmp_print*() functions to hmp.c
      monitor: move HMP-specific to monitor-hmp-internal.h
      gitlab: --disable-hmp in build-without-defaults

 .gitlab-ci.d/buildtest.yml                         |   1 +
 accel/accel-system.c                               |   3 +
 accel/tcg/monitor.c                                |   3 +
 audio/audio-hmp-cmds.c                             |  10 +-
 audio/meson.build                                  |   4 +-
 backends/cryptodev-hmp-cmds.c                      |  10 +-
 backends/meson.build                               |   5 +-
 block/monitor/block-hmp-cmds.c                     | 341 +++++++----------
 block/monitor/meson.build                          |   5 +-
 block/monitor/qmp-cmds.c                           |  79 ++++
 chardev/char-hmp-cmds.c                            |  36 +-
 chardev/char.c                                     |  11 +-
 chardev/meson.build                                |   5 +-
 disas/disas-mon.c                                  |  11 +-
 disas/meson.build                                  |   4 +-
 docs/devel/style.rst                               |   2 +-
 docs/devel/writing-monitor-commands.rst            |   8 +-
 dump/dump-hmp-cmds.c                               |  12 +-
 dump/meson.build                                   |   5 +-
 gdbstub/system.c                                   |  10 +-
 hmp-commands-info.hx                               |   6 +-
 hmp-commands.hx                                    |   9 +-
 hw/char/virtio-serial-bus.c                        |  21 +-
 hw/core/machine-hmp-cmds.c                         | 263 +++++++------
 hw/core/meson.build                                |   5 +-
 hw/core/sysbus.c                                   |  15 +-
 hw/hexagon/hexagon_tlb.c                           |  87 ++---
 hw/i386/kvm/xen-stubs.c                            |  10 +-
 hw/i386/kvm/xen_evtchn.c                           |  28 +-
 hw/i386/meson.build                                |   4 +-
 hw/i386/sgx-hmp-stub.c                             |   4 +-
 hw/i386/sgx.c                                      |  32 +-
 hw/misc/auxbus.c                                   |  29 +-
 hw/misc/mos6522-stub.c                             |   6 +-
 hw/misc/mos6522.c                                  |   7 +-
 hw/net/meson.build                                 |   4 +-
 hw/net/rocker/rocker-hmp-cmds.c                    | 158 ++++----
 hw/pci/meson.build                                 |   4 +-
 hw/pci/pci-hmp-cmds.c                              | 121 +++---
 hw/pci/pci-internal.h                              |   2 +-
 hw/pci/pci-stub.c                                  |   8 +-
 hw/pci/pci.c                                       |   2 +
 hw/s390x/s390-skeys.c                              |  14 +-
 hw/s390x/s390-stattrib.c                           |  26 +-
 hw/uefi/ovmf-log.c                                 |  10 +-
 hw/usb/bus.c                                       |  21 +-
 hw/usb/host-libusb.c                               |  29 +-
 hw/virtio/meson.build                              |   4 +-
 hw/virtio/virtio-hmp-cmds.c                        | 312 ++++++++--------
 hw/xen/xen-bus.c                                   |  11 +-
 include/block/block-hmp-cmds.h                     |  55 +--
 include/disas/disas.h                              |   4 +-
 include/hw/core/qdev.h                             |   5 +-
 include/hw/core/sysemu-cpu-ops.h                   |   2 +
 include/hw/hexagon/hexagon_tlb.h                   |   5 +-
 include/hw/usb/usb.h                               |   3 +-
 include/monitor/hmp.h                              | 334 +++++++++--------
 include/monitor/monitor.h                          |  21 --
 include/monitor/qdev.h                             |   5 +-
 include/net/net.h                                  |   8 +-
 include/net/slirp.h                                |   8 +-
 include/qemu-io.h                                  |   4 +-
 include/system/memory.h                            |   2 +
 meson.build                                        |   6 +-
 meson_options.txt                                  |   2 +
 migration/dirtyrate.c                              |  52 +--
 migration/meson.build                              |   4 +-
 migration/migration-hmp-cmds.c                     | 363 +++++++++---------
 monitor/hmp-cmds.c                                 | 290 +++++++--------
 monitor/hmp.c                                      | 257 +++++++------
 monitor/meson.build                                |   9 +-
 monitor/monitor-hmp-internal.h                     | 106 ++++++
 monitor/monitor-internal.h                         | 104 ------
 monitor/monitor.c                                  |  74 +---
 monitor/qmp-cmds.c                                 |   5 +-
 net/hub.c                                          |  29 +-
 net/hub.h                                          |   4 +-
 net/meson.build                                    |   4 +-
 net/net-hmp-cmds.c                                 |  85 +++--
 net/net.c                                          |  70 +++-
 net/slirp.c                                        |  70 ++--
 python/qemu/utils/__init__.py                      |   5 +-
 qapi/block.json                                    |  34 ++
 qapi/control.json                                  |   4 +-
 qapi/machine.json                                  |   8 +-
 qapi/misc.json                                     |   3 +-
 qapi/net.json                                      | 166 +++++++++
 qemu-io-cmds.c                                     | 414 +++++++++++----------
 qemu-io.c                                          |  17 +-
 qemu-options.hx                                    |   6 +-
 qom/meson.build                                    |   4 +-
 qom/qom-hmp-cmds.c                                 |  46 +--
 replay/replay-debugging.c                          |  20 +-
 replay/stubs-system.c                              |  14 +-
 scripts/meson-buildoptions.sh                      |   3 +
 stats/meson.build                                  |   5 +-
 stats/stats-hmp-cmds.c                             |  60 +--
 stubs/hmp-cmd-info_sev.c                           |   4 +-
 stubs/meson.build                                  |  15 +-
 stubs/monitor-core.c                               |  21 +-
 stubs/monitor-cur.c                                |  14 +
 stubs/monitor-hmp.c                                |   9 +
 stubs/monitor-internal.c                           |   4 +-
 stubs/qapi-event-emit.c                            |   8 +
 system/dirtylimit-hmp-cmds.c                       |  20 +-
 system/meson.build                                 |  11 +-
 system/physmem.c                                   |  31 ++
 system/qdev-monitor.c                              |  39 +-
 system/qtest.c                                     |  14 +
 system/runstate-hmp-cmds.c                         |  22 +-
 system/tpm-hmp-cmds.c                              |  30 +-
 system/vl.c                                        |   6 +-
 target/hexagon/hex_mmu.c                           |   6 +-
 target/hexagon/hex_mmu.h                           |   3 +-
 target/i386/cpu-apic.c                             |   8 +-
 target/i386/cpu.c                                  |   8 +-
 target/i386/cpu.h                                  |   4 +-
 target/i386/helper.c                               |  49 +--
 target/i386/kvm/kvm.c                              |   4 +-
 target/i386/monitor.c                              | 173 ++++-----
 target/i386/sev.c                                  |  38 +-
 target/m68k/cpu.c                                  |   4 +
 target/m68k/monitor.c                              |   8 +-
 target/ppc/monitor.c                               |   8 +-
 target/riscv/monitor.c                             |  61 +--
 target/rx/disas.c                                  |   1 +
 target/sh4/monitor.c                               |  34 +-
 target/sparc/cpu.c                                 |   5 +-
 target/sparc/monitor.c                             |   8 +-
 target/xtensa/monitor.c                            |   8 +-
 tests/functional/generic/test_version.py           |  10 +-
 tests/functional/qemu_test/utils.py                |   8 +-
 tests/qemu-iotests/004.out                         |  20 +-
 tests/qemu-iotests/021.out                         |  60 +--
 tests/qemu-iotests/026.out                         | 228 ++++++------
 tests/qemu-iotests/028                             |   1 +
 tests/qemu-iotests/045                             |   3 +-
 tests/qemu-iotests/051                             |   1 +
 tests/qemu-iotests/056                             |   3 +-
 tests/qemu-iotests/060                             |   1 +
 tests/qemu-iotests/060.out                         |  44 ++-
 tests/qemu-iotests/068                             |   1 +
 tests/qemu-iotests/071                             |   1 +
 tests/qemu-iotests/071.out                         |  10 +-
 tests/qemu-iotests/072.out                         |   2 +-
 tests/qemu-iotests/080.out                         |   4 +-
 tests/qemu-iotests/081                             |   1 +
 tests/qemu-iotests/081.out                         |   2 +-
 tests/qemu-iotests/083.out                         |  36 +-
 tests/qemu-iotests/089.out                         |   4 +-
 tests/qemu-iotests/091                             |   1 +
 tests/qemu-iotests/093                             |   3 +-
 tests/qemu-iotests/102                             |   1 +
 tests/qemu-iotests/114.out                         |   2 +-
 tests/qemu-iotests/117                             |   1 +
 tests/qemu-iotests/119                             |   1 +
 tests/qemu-iotests/120                             |   1 +
 tests/qemu-iotests/124                             |   3 +-
 tests/qemu-iotests/130                             |   1 +
 tests/qemu-iotests/132                             |   3 +-
 tests/qemu-iotests/134.out                         |   2 +-
 tests/qemu-iotests/136                             |   3 +-
 tests/qemu-iotests/137.out                         |   2 +-
 tests/qemu-iotests/142                             |   1 +
 tests/qemu-iotests/145                             |   1 +
 tests/qemu-iotests/146                             |   1 +
 tests/qemu-iotests/148                             |   3 +-
 tests/qemu-iotests/151                             |   3 +-
 tests/qemu-iotests/152                             |   3 +-
 tests/qemu-iotests/153                             |   1 +
 tests/qemu-iotests/153.out                         |  12 +-
 tests/qemu-iotests/156                             |   1 +
 tests/qemu-iotests/157                             |   1 +
 tests/qemu-iotests/161                             |   1 +
 tests/qemu-iotests/165                             |   3 +-
 tests/qemu-iotests/171                             |   2 +-
 tests/qemu-iotests/171.out                         |  68 ++--
 tests/qemu-iotests/172                             |   1 +
 tests/qemu-iotests/181                             |   1 +
 tests/qemu-iotests/185                             |   1 +
 tests/qemu-iotests/186                             |   1 +
 tests/qemu-iotests/192                             |   1 +
 tests/qemu-iotests/201                             |   1 +
 tests/qemu-iotests/205                             |   6 +-
 tests/qemu-iotests/214.out                         |   2 +-
 tests/qemu-iotests/216                             |   3 +-
 tests/qemu-iotests/220.out                         |   2 +-
 tests/qemu-iotests/225                             |   1 +
 tests/qemu-iotests/225.out                         |   4 +-
 tests/qemu-iotests/232                             |   1 +
 tests/qemu-iotests/236                             |   3 +-
 tests/qemu-iotests/244.out                         |  12 +-
 tests/qemu-iotests/245                             |   3 +-
 tests/qemu-iotests/246                             |   3 +-
 tests/qemu-iotests/249                             |   1 +
 tests/qemu-iotests/249.out                         |   6 +-
 tests/qemu-iotests/254                             |   3 +-
 tests/qemu-iotests/255                             |   3 +-
 tests/qemu-iotests/257                             |   3 +-
 tests/qemu-iotests/260                             |   3 +-
 tests/qemu-iotests/264                             |   3 +-
 tests/qemu-iotests/267                             |   1 +
 tests/qemu-iotests/271.out                         |  14 +-
 tests/qemu-iotests/274                             |   3 +-
 tests/qemu-iotests/280                             |   1 +
 tests/qemu-iotests/281                             |   3 +-
 tests/qemu-iotests/283                             |   1 +
 tests/qemu-iotests/286                             |   1 +
 tests/qemu-iotests/289.out                         |   2 +-
 tests/qemu-iotests/298                             |   3 +-
 tests/qemu-iotests/300                             |   3 +-
 tests/qemu-iotests/304                             |   3 +-
 tests/qemu-iotests/305.out                         |   2 +-
 tests/qemu-iotests/307.out                         |   2 +-
 tests/qemu-iotests/310                             |   3 +-
 tests/qemu-iotests/common.rc                       |   8 +
 tests/qemu-iotests/iotests.py                      |  32 +-
 tests/qemu-iotests/tests/backup-discard-source     |   7 +-
 tests/qemu-iotests/tests/copy-before-write         |  69 ++--
 tests/qemu-iotests/tests/file-io-error.out         |   2 +-
 tests/qemu-iotests/tests/image-fleecing            |   3 +-
 tests/qemu-iotests/tests/image-fleecing.out        |  12 +-
 tests/qemu-iotests/tests/inactive-node-nbd.out     |   8 +-
 tests/qemu-iotests/tests/iothreads-create          |   3 +-
 tests/qemu-iotests/tests/luks-detached-header      |   3 +-
 .../tests/migrate-bitmaps-postcopy-test            |   3 +-
 tests/qemu-iotests/tests/migrate-bitmaps-test      |   3 +-
 tests/qemu-iotests/tests/mirror-change-copy-mode   |   3 +-
 tests/qemu-iotests/tests/mirror-ready-cancel-error |   3 +-
 tests/qemu-iotests/tests/qcow2-internal-snapshots  |   1 +
 tests/qemu-iotests/tests/qsd-migrate               |   3 +-
 tests/qemu-iotests/tests/reopen-file               |   3 +-
 tests/qemu-iotests/tests/write-zeroes-unmap        |   1 +
 tests/qtest/ahci-test.c                            |   5 +-
 tests/qtest/cdrom-test.c                           |  29 +-
 tests/qtest/device-introspect-test.c               | 111 ++++--
 tests/qtest/drive_del-test.c                       |  25 ++
 tests/qtest/ide-test.c                             |   4 +-
 tests/qtest/libqtest.c                             |  14 +
 tests/qtest/libqtest.h                             |  11 +
 tests/qtest/meson.build                            |   8 +-
 tests/qtest/netdev-socket.c                        | 143 ++++---
 tests/qtest/numa-test.c                            |  63 +++-
 tests/qtest/pnv-host-i2c-test.c                    |   2 +-
 tests/qtest/pnv-xive2-test.c                       |   2 +-
 tests/qtest/qmp-test.c                             |  13 +-
 tests/unit/test-util-sockets.c                     |   1 -
 tests/vm/basevm.py                                 |  13 +-
 tools/qemu-vnc/clipboard.c                         |   4 +-
 tools/qemu-vnc/stubs.c                             |   5 -
 trace/meson.build                                  |   5 +-
 trace/trace-hmp-cmds.c                             |  17 +-
 ui/meson.build                                     |   4 +-
 ui/ui-hmp-cmds.c                                   | 151 ++++----
 util/error-report.c                                |  75 ++--
 util/qemu-print.c                                  |  14 +-
 256 files changed, 3915 insertions(+), 2940 deletions(-)
---
base-commit: 9696bf5dc5a5bf0b4a9d05b6cdfe5f13990f97aa
change-id: 20260521-qemu-no-hmp-ead3f0bf79c0

Best regards,
--  
Marc-André Lureau <marcandre.lureau@redhat.com>



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

* [PATCH v3 01/49] vl: fix -monitor none prefix matching
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 02/49] hmp: remove 'vcpu' argument from trace-event help Marc-André Lureau
                   ` (47 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Paolo Bonzini

Use g_strcmp0() for exact match instead of strncmp() which would
incorrectly treat any string starting with "none" as disabling
the monitor.

Fixes: 70e098af88f ("monitor: allow to disable the default monitor")
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 system/vl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/system/vl.c b/system/vl.c
index 061cbdf860bf..5ccc19282ba2 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -3226,7 +3226,7 @@ void qemu_init(int argc, char **argv)
                 }
             case QEMU_OPTION_monitor:
                 default_monitor = 0;
-                if (strncmp(optarg, "none", 4)) {
+                if (g_strcmp0(optarg, "none")) {
                     monitor_parse(optarg, "readline", false);
                 }
                 break;

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 02/49] hmp: remove 'vcpu' argument from trace-event help
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 01/49] vl: fix -monitor none prefix matching Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 03/49] hmp: fix snapshot_blkdev argument type Marc-André Lureau
                   ` (46 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Dr. David Alan Gilbert, Philippe Mathieu-Daudé

Fixes: 89aafcf2a793 ("trace: remove code that depends on setting vcpu")
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hmp-commands-info.hx | 6 +++---
 hmp-commands.hx      | 7 +++----
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 82134eb6c21d..2695ff04ffce 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -587,10 +587,10 @@ ERST
 
     {
         .name       = "trace-events",
-        .args_type  = "name:s?,vcpu:i?",
-        .params     = "[name] [vcpu]",
+        .args_type  = "name:s?",
+        .params     = "[name]",
         .help       = "show available trace-events & their state "
-                      "(name: event name pattern; vcpu: vCPU to query, default is any)",
+                      "(name: event name pattern)",
         .cmd = hmp_info_trace_events,
         .command_completion = info_trace_events_completion,
     },
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 43ff220b5feb..ea4a1db78f18 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -299,10 +299,9 @@ ERST
 
     {
         .name       = "trace-event",
-        .args_type  = "name:s,option:b,vcpu:i?",
-        .params     = "name on|off [vcpu]",
-        .help       = "changes status of a specific trace event "
-                      "(vcpu: vCPU to set, default is all)",
+        .args_type  = "name:s,option:b",
+        .params     = "name on|off",
+        .help       = "changes status of a specific trace event",
         .cmd = hmp_trace_event,
         .command_completion = trace_event_completion,
     },

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 03/49] hmp: fix snapshot_blkdev argument type
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 01/49] vl: fix -monitor none prefix matching Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 02/49] hmp: remove 'vcpu' argument from trace-event help Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-17  3:51   ` Philippe Mathieu-Daudé
  2026-08-16 19:12 ` [PATCH v3 04/49] target/i386: decouple cpu_x86_inject_mce() from Monitor Marc-André Lureau
                   ` (45 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Kevin Wolf,
	Hanna Reitz, Dr. David Alan Gilbert, qemu-block

The `snapshot-file` argument for `snapshot_blkdev` is mandatory. Correct
the `args_type` definition to reflect this.

Fixes: 6106e2492fe ("qapi: Convert blockdev_snapshot_sync")
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 block/monitor/block-hmp-cmds.c | 12 +-----------
 hmp-commands.hx                |  2 +-
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index 69ade0534f1c..39b82e8ef501 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -344,25 +344,15 @@ void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
 void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
 {
     const char *device = qdict_get_str(qdict, "device");
-    const char *filename = qdict_get_try_str(qdict, "snapshot-file");
+    const char *filename = qdict_get_str(qdict, "snapshot-file");
     const char *format = qdict_get_try_str(qdict, "format");
     bool reuse = qdict_get_try_bool(qdict, "reuse", false);
     enum NewImageMode mode;
     Error *err = NULL;
 
-    if (!filename) {
-        /*
-         * In the future, if 'snapshot-file' is not specified, the snapshot
-         * will be taken internally. Today it's actually required.
-         */
-        error_setg(&err, QERR_MISSING_PARAMETER, "snapshot-file");
-        goto end;
-    }
-
     mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
     qmp_blockdev_snapshot_sync(device, NULL, filename, NULL, format,
                                true, mode, &err);
-end:
     hmp_handle_error(mon, err);
 }
 
diff --git a/hmp-commands.hx b/hmp-commands.hx
index ea4a1db78f18..f0b8d8914c98 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1173,7 +1173,7 @@ ERST
 
     {
         .name       = "snapshot_blkdev",
-        .args_type  = "reuse:-n,device:B,snapshot-file:s?,format:s?",
+        .args_type  = "reuse:-n,device:B,snapshot-file:s,format:s?",
         .params     = "[-n] device [new-image-file] [format]",
         .help       = "initiates a live snapshot\n\t\t\t"
                       "of device. If a new image file is specified, the\n\t\t\t"

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 04/49] target/i386: decouple cpu_x86_inject_mce() from Monitor
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (2 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 03/49] hmp: fix snapshot_blkdev argument type Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 05/49] target/i386: return an error for invalid CPU in hmp_mce() Marc-André Lureau
                   ` (44 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Paolo Bonzini,
	Zhao Liu, Marcelo Tosatti, kvm, Philippe Mathieu-Daudé

Replace monitor_printf() error reporting with the standard **errp
pattern. Drop the Monitor *mon parameter and return bool to indicate
success, improving the function usage from non-HMP contexts. Update the
KVM MCE injection path and hmp_mce() accordingly.

Notes:
 - we may want to print the error in KVM path too

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 target/i386/cpu.h     |  4 ++--
 target/i386/helper.c  | 49 ++++++++++++++++++++++++++++---------------------
 target/i386/kvm/kvm.c |  4 ++--
 target/i386/monitor.c |  6 ++++--
 4 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index e6a197602d87..4f342b69f471 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2847,9 +2847,9 @@ void do_cpu_init(X86CPU *cpu);
 #define MCE_INJECT_BROADCAST    1
 #define MCE_INJECT_UNCOND_AO    2
 
-void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
+bool cpu_x86_inject_mce(X86CPU *cpu, int bank,
                         uint64_t status, uint64_t mcg_status, uint64_t addr,
-                        uint64_t misc, int flags);
+                        uint64_t misc, int flags, Error **errp);
 
 uint32_t cpu_cc_compute_all(CPUX86State *env1);
 
diff --git a/target/i386/helper.c b/target/i386/helper.c
index 683621416213..4133b5f244c6 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -18,6 +18,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/error.h"
 #include "qapi/qapi-events-run-state.h"
 #include "cpu.h"
 #include "exec/cputlb.h"
@@ -27,7 +28,6 @@
 #ifndef CONFIG_USER_ONLY
 #include "system/hw_accel.h"
 #include "system/memory.h"
-#include "monitor/monitor.h"
 #include "kvm/kvm_i386.h"
 #endif
 #include "qemu/log.h"
@@ -381,7 +381,7 @@ out:
 }
 
 typedef struct MCEInjectionParams {
-    Monitor *mon;
+    Error **errp;
     int bank;
     uint64_t status;
     uint64_t mcg_status;
@@ -428,9 +428,9 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
          * reporting is disabled
          */
         if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
-            monitor_printf(params->mon,
-                           "CPU %d: Uncorrected error reporting disabled\n",
-                           cs->cpu_index);
+            error_setg(params->errp,
+                "CPU %d: Uncorrected error reporting disabled",
+                cs->cpu_index);
             return;
         }
 
@@ -439,10 +439,9 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
          * reporting is disabled for the bank
          */
         if (banks[0] != ~(uint64_t)0) {
-            monitor_printf(params->mon,
-                           "CPU %d: Uncorrected error reporting disabled for"
-                           " bank %d\n",
-                           cs->cpu_index, params->bank);
+            error_setg(params->errp,
+                "CPU %d: Uncorrected error reporting disabled for bank %d",
+                cs->cpu_index, params->bank);
             return;
         }
 
@@ -459,7 +458,7 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
         if (need_reset) {
             emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar,
                                       recursive);
-            monitor_printf(params->mon, "%s", msg);
+            error_setg(params->errp, "%s", msg);
             qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
             return;
@@ -488,14 +487,15 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
     emit_guest_memory_failure(MEMORY_FAILURE_ACTION_INJECT, ar, recursive);
 }
 
-void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
+bool cpu_x86_inject_mce(X86CPU *cpu, int bank,
                         uint64_t status, uint64_t mcg_status, uint64_t addr,
-                        uint64_t misc, int flags)
+                        uint64_t misc, int flags, Error **errp)
 {
+    ERRP_GUARD();
     CPUState *cs = CPU(cpu);
     CPUX86State *cenv = &cpu->env;
     MCEInjectionParams params = {
-        .mon = mon,
+        .errp = errp,
         .bank = bank,
         .status = status,
         .mcg_status = mcg_status,
@@ -506,24 +506,27 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
     unsigned bank_num = cenv->mcg_cap & 0xff;
 
     if (!cenv->mcg_cap) {
-        monitor_printf(mon, "MCE injection not supported\n");
-        return;
+        error_setg(errp, "MCE injection not supported");
+        return false;
     }
     if (bank >= bank_num) {
-        monitor_printf(mon, "Invalid MCE bank number\n");
-        return;
+        error_setg(errp, "Invalid MCE bank number");
+        return false;
     }
     if (!(status & MCI_STATUS_VAL)) {
-        monitor_printf(mon, "Invalid MCE status code\n");
-        return;
+        error_setg(errp, "Invalid MCE status code");
+        return false;
     }
     if ((flags & MCE_INJECT_BROADCAST)
         && !cpu_x86_support_mca_broadcast(cenv)) {
-        monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
-        return;
+        error_setg(errp, "Guest CPU does not support MCA broadcast");
+        return false;
     }
 
     run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
+    if (*errp) {
+        return false;
+    }
     if (flags & MCE_INJECT_BROADCAST) {
         CPUState *other_cs;
 
@@ -537,8 +540,12 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
                 continue;
             }
             run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
+            if (*errp) {
+                return false;
+            }
         }
     }
+    return true;
 }
 
 static inline target_ulong get_memio_eip(CPUX86State *env)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 644c45fb0a02..1eeadb99adac 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -748,8 +748,8 @@ static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
         flags = 0;
     }
 
-    cpu_x86_inject_mce(NULL, cpu, 9, status, mcg_status, paddr,
-                       (MCM_ADDR_PHYS << 6) | 0xc, flags);
+    cpu_x86_inject_mce(cpu, 9, status, mcg_status, paddr,
+                       (MCM_ADDR_PHYS << 6) | 0xc, flags, NULL);
 }
 
 static void emit_hypervisor_memory_failure(MemoryFailureAction action, bool ar)
diff --git a/target/i386/monitor.c b/target/i386/monitor.c
index a536712c755a..785a13dd7107 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -580,6 +580,7 @@ void hmp_mce(Monitor *mon, const QDict *qdict)
     uint64_t addr = qdict_get_int(qdict, "addr");
     uint64_t misc = qdict_get_int(qdict, "misc");
     int flags = MCE_INJECT_UNCOND_AO;
+    Error *err = NULL;
 
     if (qdict_get_try_bool(qdict, "broadcast", false)) {
         flags |= MCE_INJECT_BROADCAST;
@@ -587,7 +588,8 @@ void hmp_mce(Monitor *mon, const QDict *qdict)
     cs = qemu_get_cpu(cpu_index);
     if (cs != NULL) {
         cpu = X86_CPU(cs);
-        cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc,
-                           flags);
+        cpu_x86_inject_mce(cpu, bank, status, mcg_status, addr, misc,
+                           flags, &err);
+        hmp_handle_error(mon, err);
     }
 }

-- 
2.55.0.543.g5ebe2ebe4ea8


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

* [PATCH v3 05/49] target/i386: return an error for invalid CPU in hmp_mce()
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (3 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 04/49] target/i386: decouple cpu_x86_inject_mce() from Monitor Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 06/49] system: move gpa2hva() to system memory unit Marc-André Lureau
                   ` (43 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Philippe Mathieu-Daudé, Paolo Bonzini, Zhao Liu,
	Philippe Mathieu-Daudé

Rather than silently doing nothing.

Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 target/i386/monitor.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/i386/monitor.c b/target/i386/monitor.c
index 785a13dd7107..9ed772e6d7f2 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -586,10 +586,12 @@ void hmp_mce(Monitor *mon, const QDict *qdict)
         flags |= MCE_INJECT_BROADCAST;
     }
     cs = qemu_get_cpu(cpu_index);
-    if (cs != NULL) {
+    if (cs) {
         cpu = X86_CPU(cs);
         cpu_x86_inject_mce(cpu, bank, status, mcg_status, addr, misc,
                            flags, &err);
-        hmp_handle_error(mon, err);
+    } else {
+        error_setg(&err, "Invalid CPU %d", cpu_index);
     }
+    hmp_handle_error(mon, err);
 }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 06/49] system: move gpa2hva() to system memory unit
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (4 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 05/49] target/i386: return an error for invalid CPU in hmp_mce() Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 07/49] system: decouple qmp_inject_nmi() from Monitor Marc-André Lureau
                   ` (42 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Paolo Bonzini,
	Peter Xu, Dr. David Alan Gilbert, Philippe Mathieu-Daudé

The function is now used by SEV code path. Move it to physmem.c rather
than hmp-cmds.c.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/monitor/monitor.h |  2 --
 include/system/memory.h   |  2 ++
 monitor/hmp-cmds.c        | 31 -------------------------------
 system/physmem.c          | 31 +++++++++++++++++++++++++++++++
 4 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 54134f2aa4fc..9f048ba103b5 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -53,8 +53,6 @@ int monitor_get_cpu_index(Monitor *mon);
 int monitor_puts_locked(Monitor *mon, const char *str);
 void monitor_flush_locked(Monitor *mon);
 
-void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp);
-
 void monitor_read_command(MonitorHMP *hmp, int show_prompt);
 int monitor_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
                           void *opaque);
diff --git a/include/system/memory.h b/include/system/memory.h
index 1dc761058f52..a7e03fc3e7c3 100644
--- a/include/system/memory.h
+++ b/include/system/memory.h
@@ -2860,4 +2860,6 @@ bool ram_block_discard_is_required(void);
 void ram_block_add_cpr_blocker(RAMBlock *rb, Error **errp);
 void ram_block_del_cpr_blocker(RAMBlock *rb);
 
+void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp);
+
 #endif
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 4e8d996dbb5b..6b1114fdaf13 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -712,37 +712,6 @@ void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
     memory_dump(mon, count, format, size, addr, true);
 }
 
-void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp)
-{
-    Int128 gpa_region_size;
-    MemoryRegionSection mrs = memory_region_find(get_system_memory(),
-                                                 addr, size);
-
-    if (!mrs.mr) {
-        error_setg(errp,
-                   "No memory is mapped at address 0x%" HWADDR_PRIx, addr);
-        return NULL;
-    }
-
-    if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) {
-        error_setg(errp,
-                   "Memory at address 0x%" HWADDR_PRIx " is not RAM", addr);
-        memory_region_unref(mrs.mr);
-        return NULL;
-    }
-
-    gpa_region_size = int128_make64(size);
-    if (int128_lt(mrs.size, gpa_region_size)) {
-        error_setg(errp, "Size of memory region at 0x%" HWADDR_PRIx
-                   " exceeded.", addr);
-        memory_region_unref(mrs.mr);
-        return NULL;
-    }
-
-    *p_mr = mrs.mr;
-    return qemu_map_ram_ptr(mrs.mr->ram_block, mrs.offset_within_region);
-}
-
 void hmp_gpa2hva(Monitor *mon, const QDict *qdict)
 {
     hwaddr addr = qdict_get_int(qdict, "addr");
diff --git a/system/physmem.c b/system/physmem.c
index 362a00f76c03..a4a6a4710c64 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -4534,3 +4534,34 @@ void ram_block_del_cpr_blocker(RAMBlock *rb)
 {
     migrate_del_blocker(&rb->cpr_blocker);
 }
+
+void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp)
+{
+    Int128 gpa_region_size;
+    MemoryRegionSection mrs = memory_region_find(get_system_memory(),
+                                                 addr, size);
+
+    if (!mrs.mr) {
+        error_setg(errp,
+                   "No memory is mapped at address 0x%" HWADDR_PRIx, addr);
+        return NULL;
+    }
+
+    if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) {
+        error_setg(errp,
+                   "Memory at address 0x%" HWADDR_PRIx " is not RAM", addr);
+        memory_region_unref(mrs.mr);
+        return NULL;
+    }
+
+    gpa_region_size = int128_make64(size);
+    if (int128_lt(mrs.size, gpa_region_size)) {
+        error_setg(errp, "Size of memory region at 0x%" HWADDR_PRIx
+                   " exceeded.", addr);
+        memory_region_unref(mrs.mr);
+        return NULL;
+    }
+
+    *p_mr = mrs.mr;
+    return qemu_map_ram_ptr(mrs.mr->ram_block, mrs.offset_within_region);
+}

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 07/49] system: decouple qmp_inject_nmi() from Monitor
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (5 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 06/49] system: move gpa2hva() to system memory unit Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-17  3:53   ` Philippe Mathieu-Daudé
  2026-08-16 19:12 ` [PATCH v3 08/49] monitor: move HMP-only fields from Monitor to MonitorHMP Marc-André Lureau
                   ` (41 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Eric Blake, Zhao Liu

Use first_cpu directly instead of going through monitor_get_cpu_index(),
as this is HMP-territory. QMP doesn't have a `cpu` command, we should
add arguments instead when needed.

Update the inject-nmi doc to accurately describe per-architecture NMI
delivery.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 qapi/machine.json | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/qapi/machine.json b/qapi/machine.json
index 2d63c1bac3b4..29ab1cb9d7f4 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -432,10 +432,10 @@
 ##
 # @inject-nmi:
 #
-# Injects a Non-Maskable Interrupt (machine specific: for example on
-# s390x CCW only the first vCPU receives the NMI, but on x86 machines
-# all vCPUs receive it).  The command fails when the guest doesn't
-# support injecting.
+# Injects a Non-Maskable Interrupt into the virtual machine.  The NMI
+# is delivered to all vCPUs (x86, hppa, ppc64) or to the first vCPU
+# (s390).  The command fails when the guest doesn't support
+# injecting.
 #
 # Since: 0.14
 #

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 08/49] monitor: move HMP-only fields from Monitor to MonitorHMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (6 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 07/49] system: decouple qmp_inject_nmi() from Monitor Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 09/49] tests/functional: use query-version QMP command instead of HMP Marc-André Lureau
                   ` (40 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Dr. David Alan Gilbert, Philippe Mathieu-Daudé

mon_cpu_path and reset_seen are only used by HMP monitors; move them
from the base Monitor struct into MonitorHMP to properly encapsulate
HMP-specific state.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 monitor/hmp-cmds.c         | 16 +++++++++-------
 monitor/hmp.c              |  9 +++++----
 monitor/monitor-internal.h |  4 ++--
 monitor/monitor.c          |  1 -
 4 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 6b1114fdaf13..6718fec97047 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -499,31 +499,33 @@ void hmp_dumpdtb(Monitor *mon, const QDict *qdict)
 /* Set the current CPU defined by the user. Callers must hold BQL. */
 int monitor_set_cpu(Monitor *mon, int cpu_index)
 {
+    MonitorHMP *hmp_mon = MONITOR_HMP(mon);
     CPUState *cpu;
 
     cpu = qemu_get_cpu(cpu_index);
     if (cpu == NULL) {
         return -1;
     }
-    g_free(mon->mon_cpu_path);
-    mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
+    g_free(hmp_mon->mon_cpu_path);
+    hmp_mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
     return 0;
 }
 
 /* Callers must hold BQL. */
 static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize)
 {
+    MonitorHMP *hmp_mon = MONITOR_HMP(mon);
     CPUState *cpu = NULL;
 
-    if (mon->mon_cpu_path) {
-        cpu = (CPUState *) object_resolve_path_type(mon->mon_cpu_path,
+    if (hmp_mon->mon_cpu_path) {
+        cpu = (CPUState *) object_resolve_path_type(hmp_mon->mon_cpu_path,
                                                     TYPE_CPU, NULL);
         if (!cpu) {
-            g_free(mon->mon_cpu_path);
-            mon->mon_cpu_path = NULL;
+            g_free(hmp_mon->mon_cpu_path);
+            hmp_mon->mon_cpu_path = NULL;
         }
     }
-    if (!mon->mon_cpu_path) {
+    if (!hmp_mon->mon_cpu_path) {
         if (!first_cpu) {
             return NULL;
         }
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 22b1972d346a..8134dfaad4bb 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -50,6 +50,7 @@ OBJECT_DEFINE_TYPE(MonitorHMP, monitor_hmp, MONITOR_HMP, MONITOR);
 static void monitor_hmp_finalize(Object *obj)
 {
     MonitorHMP *hmp = MONITOR_HMP(obj);
+    g_free(hmp->mon_cpu_path);
     if (hmp->rs) {
         readline_free(hmp->rs);
     }
@@ -112,8 +113,8 @@ int monitor_hmp_vprintf(Monitor *mon, const char *fmt, va_list ap)
 static void monitor_hmp_accept_input(Monitor *mon)
 {
     qemu_mutex_lock(&mon->mon_lock);
-    if (mon->reset_seen) {
-        MonitorHMP *hmp = MONITOR_HMP(mon);
+    MonitorHMP *hmp = MONITOR_HMP(mon);
+    if (hmp->reset_seen) {
         assert(hmp->rs);
         readline_restart(hmp->rs);
         qemu_chr_fe_accept_input(&mon->chr);
@@ -1556,7 +1557,7 @@ static void monitor_event(void *opaque, QEMUChrEvent event)
     case CHR_EVENT_MUX_OUT:
         qemu_mutex_lock(&mon->mon_lock);
         if (!mon->mux_out) {
-            if (mon->reset_seen && !mon->suspend_cnt) {
+            if (hmp->reset_seen && !mon->suspend_cnt) {
                 monitor_puts_locked(mon, "\n");
             } else {
                 monitor_flush_locked(mon);
@@ -1573,7 +1574,7 @@ static void monitor_event(void *opaque, QEMUChrEvent event)
         monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
                        "information\n", QEMU_VERSION);
         qemu_mutex_lock(&mon->mon_lock);
-        mon->reset_seen = 1;
+        hmp->reset_seen = 1;
         if (!mon->mux_out && hmp->use_readline) {
             /* Suspend-resume forces the prompt to be printed.  */
             monitor_suspend(mon);
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index e0a124a317a5..fdeeeb853636 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -137,7 +137,6 @@ struct Monitor {
     CharFrontend chr;
     int suspend_cnt;            /* Needs to be accessed atomically */
     QEMUBH *accept_input_bh;    /* persistent BH for monitor_accept_input */
-    char *mon_cpu_path;
     QTAILQ_ENTRY(Monitor) entry;
 
     /*
@@ -153,7 +152,6 @@ struct Monitor {
     GString *outbuf;
     guint out_watch;
     int mux_out;
-    int reset_seen;
 };
 
 struct MonitorHMPClass {
@@ -170,6 +168,8 @@ struct MonitorHMP {
      * These members can be safely accessed without locks.
      */
     ReadLineState *rs;
+    char *mon_cpu_path;
+    int reset_seen;
 };
 
 struct MonitorQMPClass {
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 6af09f2f6eac..6d6ffbb0f78a 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -89,7 +89,6 @@ static void monitor_finalize(Object *obj)
         qemu_bh_delete(mon->accept_input_bh);
     }
     g_free(mon->chardev_id);
-    g_free(mon->mon_cpu_path);
     qemu_chr_fe_deinit(&mon->chr, false);
     g_string_free(mon->outbuf, true);
     qemu_mutex_destroy(&mon->mon_lock);

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 09/49] tests/functional: use query-version QMP command instead of HMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (7 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 08/49] monitor: move HMP-only fields from Monitor to MonitorHMP Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 10/49] net/qapi: add x-query-usernet command Marc-André Lureau
                   ` (39 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Philippe Mathieu-Daudé

Replace the human-monitor-command based version test with the native
QMP query-version command, which returns structured version data.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/functional/generic/test_version.py | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/tests/functional/generic/test_version.py b/tests/functional/generic/test_version.py
index 3ab3b67f7e39..7764424826e0 100755
--- a/tests/functional/generic/test_version.py
+++ b/tests/functional/generic/test_version.py
@@ -16,13 +16,15 @@
 
 class Version(QemuSystemTest):
 
-    def test_qmp_human_info_version(self):
+    def test_qmp_query_version(self):
         self.set_machine('none')
         self.vm.add_args('-nodefaults')
         self.vm.launch()
-        res = self.vm.cmd('human-monitor-command',
-                          command_line='info version')
-        self.assertRegex(res, r'^(\d+\.\d+\.\d)')
+        res = self.vm.cmd('query-version')
+        version = res['qemu']
+        self.assertIsInstance(version['major'], int)
+        self.assertIsInstance(version['minor'], int)
+        self.assertIsInstance(version['micro'], int)
 
 if __name__ == '__main__':
     QemuSystemTest.main()

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 10/49] net/qapi: add x-query-usernet command
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (8 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 09/49] tests/functional: use query-version QMP command instead of HMP Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 11/49] python, tests: switch usernet queries from HMP to QMP Marc-André Lureau
                   ` (38 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Samuel Thibault,
	Jason Wang, Eric Blake

Add a QMP command to query user-mode network stack (slirp) connection
states, providing a structured alternative to "info usernet" HMP.

The new command returns a list of UsernetInfo, with hub-id, hub-name,
and connection info for each slirp stack. It is marked unstable as it
is meant for debugging.

Rewrite hmp_info_usernet() as a thin wrapper over qmp_x_query_usernet()
so the HMP and QMP paths share the same implementation.

This is part of the effort to decouple HMP from QEMU core.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
---
 net/slirp.c   | 34 ++++++++++++++++++++++++++++------
 qapi/net.json | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 9e9941fe73e7..517dd23be14b 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -43,6 +43,7 @@
 #include "system/system.h"
 #include "qemu/cutils.h"
 #include "qapi/error.h"
+#include "qapi/qapi-commands-net.h"
 #include "qobject/qdict.h"
 #include "util.h"
 #include "migration/register.h"
@@ -1200,18 +1201,39 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
     return -1;
 }
 
-void hmp_info_usernet(Monitor *mon, const QDict *qdict)
+UsernetInfoList *qmp_x_query_usernet(Error **errp)
 {
+    UsernetInfoList *head = NULL, **tail = &head;
     SlirpState *s;
 
     QTAILQ_FOREACH(s, &slirp_stacks, entry) {
+        UsernetInfo *ui = g_new0(UsernetInfo, 1);
         int id;
-        bool got_hub_id = net_hub_id_for_client(&s->nc, &id) == 0;
-        char *info = slirp_connection_info(s->slirp);
+
+        if (net_hub_id_for_client(&s->nc, &id) == 0) {
+            ui->has_hub_id = true;
+            ui->hub_id = id;
+        }
+        ui->hub_name = g_strdup(s->nc.name);
+        ui->info = slirp_connection_info(s->slirp);
+
+        QAPI_LIST_APPEND(tail, ui);
+    }
+
+    return head;
+}
+
+void hmp_info_usernet(Monitor *mon, const QDict *qdict)
+{
+    g_autoptr(UsernetInfoList) list = NULL;
+    UsernetInfoList *entry;
+
+    list = qmp_x_query_usernet(&error_abort);
+    for (entry = list; entry; entry = entry->next) {
+        UsernetInfo *ui = entry->value;
         monitor_printf(mon, "Hub %d (%s):\n%s",
-                       got_hub_id ? id : -1,
-                       s->nc.name, info);
-        g_free(info);
+                       ui->has_hub_id ? (int)ui->hub_id : -1,
+                       ui->hub_name, ui->info);
     }
 }
 
diff --git a/qapi/net.json b/qapi/net.json
index 1a6382825c5e..5d3342fba23b 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -1261,3 +1261,47 @@
 ##
 { 'event': 'NETDEV_VHOST_USER_DISCONNECTED',
   'data': { 'netdev-id': 'str' } }
+
+##
+# @UsernetInfo:
+#
+# Information about a user-mode network stack (slirp).
+#
+# @hub-id: The hub id, if available.
+#
+# @hub-name: The name of the hub.
+#
+# @info: Network information from slirp.
+#
+# Since: 11.2
+##
+{ 'struct': 'UsernetInfo',
+  'data': {
+    '*hub-id': 'int',
+    'hub-name': 'str',
+    'info': 'str' },
+  'if': 'CONFIG_SLIRP' }
+
+##
+# @x-query-usernet:
+#
+# Query user-mode network stack connection states.
+#
+# Features:
+#
+# @unstable: This command is meant for debugging.
+#
+# Returns: list of user-mode network stack information.
+#
+# Since: 11.2
+#
+# .. qmp-example::
+#
+#     -> { "execute": "x-query-usernet" }
+#     <- { "return": [ { "hub-id": 0, "hub-name": "vnet",
+#                        "info": "..." } ] }
+##
+{ 'command': 'x-query-usernet',
+  'returns': ['UsernetInfo'],
+  'if': 'CONFIG_SLIRP',
+  'features': [ 'unstable' ] }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 11/49] python, tests: switch usernet queries from HMP to QMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (9 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 10/49] net/qapi: add x-query-usernet command Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-17  7:30   ` Thomas Huth
  2026-08-16 19:12 ` [PATCH v3 12/49] tests/qtest/pnv: drop unnecessary -serial mon:stdio Marc-André Lureau
                   ` (37 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, John Snow,
	Cleber Rosa, Thomas Huth, Alex Bennée, Pierrick Bouvier

Replace human-monitor-command "info usernet" calls with the structured
x-query-usernet QMP command in get_usernet_hostfwd_port() and the VM
test runner boot path.

Since x-query-usernet returns a list of UsernetInfo entries, callers
now iterate over the result and extract the port from each entry's
"info" field. Also switch get_info_usernet_hostfwd_port() from
split('\r\n') to splitlines(), since QMP strings use \n rather than
the HMP monitor's \r\n line endings.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
---
 python/qemu/utils/__init__.py       |  5 +++--
 tests/functional/qemu_test/utils.py |  8 ++++++--
 tests/vm/basevm.py                  | 13 ++++++++-----
 3 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/python/qemu/utils/__init__.py b/python/qemu/utils/__init__.py
index be5daa836340..e32911d4c6df 100644
--- a/python/qemu/utils/__init__.py
+++ b/python/qemu/utils/__init__.py
@@ -46,10 +46,11 @@ def get_info_usernet_hostfwd_port(info_usernet_output: str) -> Optional[int]:
     """
     Returns the port given to the hostfwd parameter via info usernet
 
-    :param info_usernet_output: output generated by hmp command "info usernet"
+    :param info_usernet_output: output generated by "info usernet" or
+        the "info" field from x-query-usernet
     :return: the port number allocated by the hostfwd option
     """
-    for line in info_usernet_output.split('\r\n'):
+    for line in info_usernet_output.splitlines():
         regex = r'TCP.HOST_FORWARD.*127\.0\.0\.1\s+(\d+)\s+10\.'
         match = re.search(regex, line)
         if match is not None:
diff --git a/tests/functional/qemu_test/utils.py b/tests/functional/qemu_test/utils.py
index 826c267785bd..0992db49ab28 100644
--- a/tests/functional/qemu_test/utils.py
+++ b/tests/functional/qemu_test/utils.py
@@ -14,8 +14,12 @@
 
 
 def get_usernet_hostfwd_port(vm):
-    res = vm.cmd('human-monitor-command', command_line='info usernet')
-    return get_info_usernet_hostfwd_port(res)
+    res = vm.cmd('x-query-usernet')
+    for entry in res:
+        port = get_info_usernet_hostfwd_port(entry['info'])
+        if port is not None:
+            return port
+    return None
 
 def pow2ceil(x):
     """
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 9e879e966a36..198b04e8c375 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -312,12 +312,15 @@ def boot(self, img, extra_args=[]):
         self._guest = guest
         # Init console so we can start consuming the chars.
         self.console_init()
-        usernet_info = guest.cmd("human-monitor-command",
-                                 command_line="info usernet")
-        self.ssh_port = get_info_usernet_hostfwd_port(usernet_info)
+        res = guest.cmd("x-query-usernet")
+        for entry in res:
+            port = get_info_usernet_hostfwd_port(entry['info'])
+            if port is not None:
+                self.ssh_port = port
+                break
         if not self.ssh_port:
-            raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
-                            usernet_info)
+            raise Exception("Cannot find ssh port from"
+                            " 'x-query-usernet': %s" % res)
 
     def console_init(self, timeout = None):
         if timeout == None:

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 12/49] tests/qtest/pnv: drop unnecessary -serial mon:stdio
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (10 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 11/49] python, tests: switch usernet queries from HMP to QMP Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 13/49] tests/qtest/qmp-test: don't depend on human-monitor-command Marc-André Lureau
                   ` (36 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Nicholas Piggin,
	Aditya Gupta, Glenn Miles, Harsh Prateek Bora, Fabiano Rosas,
	Laurent Vivier, Paolo Bonzini, Gautam Menghani, qemu-ppc,
	Philippe Mathieu-Daudé

The pnv-xive2-test and pnv-host-i2c-test pass "-serial mon:stdio"
but never use HMP commands. The "mon:" chardev prefix creates an
HMP monitor mux, which fails when HMP is disabled. Other pnv tests
(e.g. pnv-spi-seeprom-test) don't specify -serial at all.

Drop the unnecessary -serial mon:stdio option.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/qtest/pnv-host-i2c-test.c | 2 +-
 tests/qtest/pnv-xive2-test.c    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/qtest/pnv-host-i2c-test.c b/tests/qtest/pnv-host-i2c-test.c
index 5fd54f9de771..f97f6f65eed3 100644
--- a/tests/qtest/pnv-host-i2c-test.c
+++ b/tests/qtest/pnv-host-i2c-test.c
@@ -414,7 +414,7 @@ static void test_host_i2c(const void *data)
     }
 
     qts = qtest_initf("-M %s -smp %d,cores=1,threads=%d -nographic "
-                      "-nodefaults -serial mon:stdio -S "
+                      "-nodefaults -S "
                       "-d guest_errors",
                       machine, SMT, SMT);
 
diff --git a/tests/qtest/pnv-xive2-test.c b/tests/qtest/pnv-xive2-test.c
index 9f67a0066864..a0892c0f8e89 100644
--- a/tests/qtest/pnv-xive2-test.c
+++ b/tests/qtest/pnv-xive2-test.c
@@ -552,7 +552,7 @@ static void test_xive(const void *data)
     QTestState *qts;
 
     qts = qtest_initf("-M %s -smp %d,cores=1,threads=%d -nographic "
-                      "-nodefaults -serial mon:stdio -S "
+                      "-nodefaults -S "
                       "-d guest_errors -trace '*xive*'",
                       machine, SMT, SMT);
     init_xive(qts);

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 13/49] tests/qtest/qmp-test: don't depend on human-monitor-command
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (11 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 12/49] tests/qtest/pnv: drop unnecessary -serial mon:stdio Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-17  3:55   ` Philippe Mathieu-Daudé
  2026-08-16 19:12 ` [PATCH v3 14/49] tests/qtest/numa-test: replace HMP "info numa" with QMP query-cpus-fast Marc-André Lureau
                   ` (35 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Fabiano Rosas,
	Laurent Vivier, Paolo Bonzini

The test was using 'human-monitor-command' (which requires HMP) to
verify that an integer 'id' is echoed back on failure. Replace with
'query-name' for the success case and 'block_resize' (missing
required args) for the failure case, so the test works regardless of
HMP availability.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/qtest/qmp-test.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/tests/qtest/qmp-test.c b/tests/qtest/qmp-test.c
index 3a325a04e07b..927ab053f8ab 100644
--- a/tests/qtest/qmp-test.c
+++ b/tests/qtest/qmp-test.c
@@ -151,9 +151,14 @@ static void test_qmp_protocol(void)
     g_assert_cmpstr(qdict_get_try_str(resp, "id"), ==, "cookie#1");
     qobject_unref(resp);
 
-    /* Test command failure with 'id' */
-    resp = qtest_qmp(qts, "{ 'execute': 'human-monitor-command', 'id': 2 }");
+    /* Test integer 'id' is echoed back on success */
+    resp = qtest_qmp(qts, "{ 'execute': 'query-name', 'id': 2 }");
     g_assert_cmpint(qdict_get_int(resp, "id"), ==, 2);
+    qobject_unref(resp);
+
+    /* Test integer 'id' is echoed back on failure */
+    resp = qtest_qmp(qts, "{ 'execute': 'block_resize', 'id': 3 }");
+    g_assert_cmpint(qdict_get_int(resp, "id"), ==, 3);
     qmp_expect_error_and_unref(resp, "GenericError");
 
     qtest_quit(qts);
@@ -487,6 +492,7 @@ static void test_qmp_monitor_remove_cli(void)
     qtest_quit(qts);
 }
 
+#ifdef CONFIG_HMP
 static void test_qmp_monitor_remove_hmp(void)
 {
     QTestState *qts;
@@ -504,6 +510,7 @@ static void test_qmp_monitor_remove_hmp(void)
 
     qtest_quit(qts);
 }
+#endif
 
 int main(int argc, char *argv[])
 {
@@ -521,7 +528,9 @@ int main(int argc, char *argv[])
     qtest_add_func("qmp/monitor-chardev-in-use",
                     test_qmp_monitor_chardev_in_use);
     qtest_add_func("qmp/monitor-remove-cli", test_qmp_monitor_remove_cli);
+#ifdef CONFIG_HMP
     qtest_add_func("qmp/monitor-remove-hmp", test_qmp_monitor_remove_hmp);
+#endif
 
     return g_test_run();
 }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 14/49] tests/qtest/numa-test: replace HMP "info numa" with QMP query-cpus-fast
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (12 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 13/49] tests/qtest/qmp-test: don't depend on human-monitor-command Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 15/49] tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block Marc-André Lureau
                   ` (34 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Fabiano Rosas,
	Laurent Vivier, Paolo Bonzini

Convert the three test functions that relied on HMP "info numa" to use
QMP "query-cpus-fast" instead, verifying each CPU's node-id through the
structured response. Add a check_cpu_node() helper for the per-CPU
assertions.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/qtest/numa-test.c | 63 +++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 51 insertions(+), 12 deletions(-)

diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
index d657f3894743..8f563c079f62 100644
--- a/tests/qtest/numa-test.c
+++ b/tests/qtest/numa-test.c
@@ -19,19 +19,50 @@ static char *make_cli(const GString *generic_cli, const char *test_cli)
     return g_strdup_printf("%s %s", generic_cli->str, test_cli);
 }
 
+static void check_cpu_node(QTestState *qts, int cpu_idx, int expected_node)
+{
+    QDict *resp;
+    QList *cpus;
+    QListEntry *e;
+    bool found = false;
+
+    resp = qtest_qmp(qts, "{ 'execute': 'query-cpus-fast' }");
+    g_assert(resp);
+    g_assert(qdict_haskey(resp, "return"));
+    cpus = qdict_get_qlist(resp, "return");
+    g_assert(cpus);
+
+    QLIST_FOREACH_ENTRY(cpus, e) {
+        QDict *cpu = qobject_to(QDict, qlist_entry_obj(e));
+        int64_t idx = qdict_get_int(cpu, "cpu-index");
+        if (idx == cpu_idx) {
+            QDict *props = qdict_get_qdict(cpu, "props");
+            g_assert(qdict_haskey(props, "node-id"));
+            g_assert_cmpint(qdict_get_int(props, "node-id"), ==, expected_node);
+            found = true;
+            break;
+        }
+    }
+    g_assert(found);
+    qobject_unref(resp);
+}
+
 static void test_mon_explicit(const void *data)
 {
     QTestState *qts;
-    g_autofree char *s = NULL;
     g_autofree char *cli = NULL;
+    int i;
 
     cli = make_cli(data, "-machine smp.cpus=8 -numa node,nodeid=0,memdev=ram,cpus=0-3 "
                          "-numa node,nodeid=1,cpus=4-7");
     qts = qtest_init(cli);
 
-    s = qtest_hmp(qts, "info numa");
-    g_assert(strstr(s, "node 0 cpus: 0 1 2 3"));
-    g_assert(strstr(s, "node 1 cpus: 4 5 6 7"));
+    for (i = 0; i < 4; i++) {
+        check_cpu_node(qts, i, 0);
+    }
+    for (i = 4; i < 8; i++) {
+        check_cpu_node(qts, i, 1);
+    }
 
     qtest_quit(qts);
 }
@@ -39,16 +70,19 @@ static void test_mon_explicit(const void *data)
 static void test_def_cpu_split(const void *data)
 {
     QTestState *qts;
-    g_autofree char *s = NULL;
     g_autofree char *cli = NULL;
+    int even_cpus[] = {0, 2, 4, 6};
+    int odd_cpus[] = {1, 3, 5, 7};
+    int i;
 
     cli = make_cli(data, "-machine smp.cpus=8,smp.sockets=8 "
                          "-numa node,memdev=ram -numa node");
     qts = qtest_init(cli);
 
-    s = qtest_hmp(qts, "info numa");
-    g_assert(strstr(s, "node 0 cpus: 0 2 4 6"));
-    g_assert(strstr(s, "node 1 cpus: 1 3 5 7"));
+    for (i = 0; i < 4; i++) {
+        check_cpu_node(qts, even_cpus[i], 0);
+        check_cpu_node(qts, odd_cpus[i], 1);
+    }
 
     qtest_quit(qts);
 }
@@ -56,17 +90,22 @@ static void test_def_cpu_split(const void *data)
 static void test_mon_partial(const void *data)
 {
     QTestState *qts;
-    g_autofree char *s = NULL;
     g_autofree char *cli = NULL;
+    int node0_cpus[] = {0, 1, 2, 3, 6, 7};
+    int node1_cpus[] = {4, 5};
+    int i;
 
     cli = make_cli(data, "-machine smp.cpus=8 "
                    "-numa node,nodeid=0,memdev=ram,cpus=0-1 "
                    "-numa node,nodeid=1,cpus=4-5 ");
     qts = qtest_init(cli);
 
-    s = qtest_hmp(qts, "info numa");
-    g_assert(strstr(s, "node 0 cpus: 0 1 2 3 6 7"));
-    g_assert(strstr(s, "node 1 cpus: 4 5"));
+    for (i = 0; i < 6; i++) {
+        check_cpu_node(qts, node0_cpus[i], 0);
+    }
+    for (i = 0; i < 2; i++) {
+        check_cpu_node(qts, node1_cpus[i], 1);
+    }
 
     qtest_quit(qts);
 }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 15/49] tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (13 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 14/49] tests/qtest/numa-test: replace HMP "info numa" with QMP query-cpus-fast Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:53   ` Denis V. Lunev
  2026-08-16 19:12 ` [PATCH v3 16/49] tests/qtest/device-introspect-test: fix test without HMP Marc-André Lureau
                   ` (33 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, John Snow,
	Denis V. Lunev, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	qemu-block, Philippe Mathieu-Daudé

The test_cdrom_param() function uses qtest_hmp() to run "info block",
which depends on the human-monitor-command QMP endpoint. Replace it
with the QMP query-block command so the test works when HMP is
disabled (-Dhmp=disabled).

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/qtest/cdrom-test.c | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/tests/qtest/cdrom-test.c b/tests/qtest/cdrom-test.c
index a65854d2bc53..bf997be6d690 100644
--- a/tests/qtest/cdrom-test.c
+++ b/tests/qtest/cdrom-test.c
@@ -14,6 +14,7 @@
 #include "libqtest.h"
 #include "boot-sector.h"
 #include "qobject/qdict.h"
+#include "qobject/qlist.h"
 
 static char isoimage[] = "cdrom-boot-iso-XXXXXX";
 
@@ -92,17 +93,35 @@ cleanup:
 
 /**
  * Check that at least the -cdrom parameter is basically working, i.e. we can
- * see the filename of the ISO image in the output of "info block" afterwards
+ * see the filename of the ISO image in the output of "query-block" afterwards
  */
 static void test_cdrom_param(gconstpointer data)
 {
     QTestState *qts;
-    char *resp;
+    QDict *response;
+    QList *ret;
+    QListEntry *entry;
+    bool found = false;
 
     qts = qtest_initf("-M %s -cdrom %s", (const char *)data, isoimage);
-    resp = qtest_hmp(qts, "info block");
-    g_assert(strstr(resp, isoimage) != 0);
-    g_free(resp);
+    response = qtest_qmp(qts, "{'execute': 'query-block'}");
+    g_assert(response && qdict_haskey(response, "return"));
+    ret = qdict_get_qlist(response, "return");
+
+    QLIST_FOREACH_ENTRY(ret, entry) {
+        QDict *entry_dict = qobject_to(QDict, entry->value);
+        QDict *inserted = qdict_get_qdict(entry_dict, "inserted");
+        if (inserted) {
+            const char *file = qdict_get_str(inserted, "file");
+            if (file && strstr(file, isoimage)) {
+                found = true;
+                break;
+            }
+        }
+    }
+
+    g_assert(found);
+    qobject_unref(response);
     qtest_quit(qts);
 }
 

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 16/49] tests/qtest/device-introspect-test: fix test without HMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (14 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 15/49] tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 17/49] tests/qemu-iotests/205: fix race in assertExportNotFound Marc-André Lureau
                   ` (32 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Fabiano Rosas,
	Laurent Vivier, Paolo Bonzini

Replace "info qom-tree" with recursive qom-list walk.
Disable HMP-only code paths, info qtree, kinda duplicating the test.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/qtest/device-introspect-test.c | 111 +++++++++++++++++++++++++++--------
 1 file changed, 88 insertions(+), 23 deletions(-)

diff --git a/tests/qtest/device-introspect-test.c b/tests/qtest/device-introspect-test.c
index f84cec51dc2e..f6eca2c8eb7e 100644
--- a/tests/qtest/device-introspect-test.c
+++ b/tests/qtest/device-introspect-test.c
@@ -11,10 +11,10 @@
  */
 
 /*
- * Covers QMP device-list-properties and HMP device_add help.  We
- * currently don't check that their output makes sense, only that QEMU
- * survives.  Useful since we've had an astounding number of crash
- * bugs around here.
+ * Covers QMP device-list-properties and HMP device_add help (if
+ * CONFIG_HMP).  We currently don't check that the output makes sense,
+ * only that QEMU survives.  Useful since we've had an astounding
+ * number of crash bugs around here.
  */
 
 #include "qemu/osdep.h"
@@ -100,11 +100,60 @@ static QList *device_type_list(QTestState *qts, bool abstract)
     return qom_list_types(qts, "device", abstract);
 }
 
+/*
+ * Recursively walk the QOM composition tree via qom-list and build a
+ * string representation.  This serves two purposes: detecting dangling
+ * pointers (qom-list would crash QEMU) and detecting leaked objects
+ * (by comparing the output before and after device introspection).
+ */
+static void qom_tree_walk(QTestState *qts, const char *path, GString *result)
+{
+    QDict *resp;
+    QList *list;
+    QListEntry *e;
+    GList *children = NULL;
+
+    resp = qtest_qmp(qts, "{'execute': 'qom-list',"
+                     " 'arguments': {'path': %s}}", path);
+    g_assert(qdict_haskey(resp, "return"));
+    list = qdict_get_qlist(resp, "return");
+
+    QLIST_FOREACH_ENTRY(list, e) {
+        QDict *prop = qobject_to(QDict, qlist_entry_obj(e));
+        const char *type = qdict_get_str(prop, "type");
+        if (g_str_has_prefix(type, "child<")) {
+            const char *name = qdict_get_str(prop, "name");
+            children = g_list_prepend(children, g_strdup(name));
+        }
+    }
+
+    children = g_list_sort_with_data(children, (GCompareDataFunc)g_strcmp0,
+                                     NULL);
+
+    for (GList *l = children; l; l = l->next) {
+        const char *name = l->data;
+        g_autofree char *child_path = (!strcmp(path, "/"))
+            ? g_strdup_printf("/%s", name)
+            : g_strdup_printf("%s/%s", path, name);
+
+        g_string_append_printf(result, "%s\n", child_path);
+        qom_tree_walk(qts, child_path, result);
+    }
+
+    g_list_free_full(children, g_free);
+    qobject_unref(resp);
+}
+
+static char *qom_tree_str(QTestState *qts)
+{
+    GString *result = g_string_new("");
+    qom_tree_walk(qts, "/", result);
+    return g_string_free(result, FALSE);
+}
+
 static void test_one_device(QTestState *qts, const char *type)
 {
     QDict *resp;
-    char *help, *escaped;
-    GRegex *comma;
 
     g_test_message("Testing device '%s'", type);
 
@@ -113,19 +162,21 @@ static void test_one_device(QTestState *qts, const char *type)
                type);
     qobject_unref(resp);
 
-    comma = g_regex_new(",", 0, 0, NULL);
-    escaped = g_regex_replace_literal(comma, type, -1, 0, ",,", 0, NULL);
-    g_regex_unref(comma);
+#ifdef CONFIG_HMP
+    {
+        g_autofree char *escaped = NULL;
+        g_autoptr(GRegex) comma = NULL;
 
-    help = qtest_hmp(qts, "device_add \"%s,help\"", escaped);
-    g_free(help);
-    g_free(escaped);
+        comma = g_regex_new(",", 0, 0, NULL);
+        escaped = g_regex_replace_literal(comma, type, -1, 0, ",,", 0, NULL);
+        g_free(qtest_hmp(qts, "device_add \"%s,help\"", escaped));
+    }
+#endif
 }
 
 static void test_device_intro_list(void)
 {
     QList *types;
-    char *help;
     QTestState *qts;
 
     qts = qtest_init(common_args);
@@ -133,8 +184,11 @@ static void test_device_intro_list(void)
     types = device_type_list(qts, true);
     qobject_unref(types);
 
-    help = qtest_hmp(qts, "device_add help");
-    g_free(help);
+#ifdef CONFIG_HMP
+    {
+        g_free(qtest_hmp(qts, "device_add help"));
+    }
+#endif
 
     qtest_quit(qts);
 }
@@ -198,18 +252,22 @@ static void test_qom_list_fields(void)
 static void test_device_intro_none(void)
 {
     QTestState *qts = qtest_init(common_args);
-    g_autofree char *qom_tree_start = qtest_hmp(qts, "info qom-tree");
+    g_autofree char *qom_tree_start = qom_tree_str(qts);
     g_autofree char *qom_tree_end = NULL;
+#ifdef CONFIG_HMP
     g_autofree char *qtree_start = qtest_hmp(qts, "info qtree");
     g_autofree char *qtree_end = NULL;
+#endif
 
     test_one_device(qts, "nonexistent");
 
     /* Make sure that really nothing changed in the trees */
-    qom_tree_end = qtest_hmp(qts, "info qom-tree");
+    qom_tree_end = qom_tree_str(qts);
     g_assert_cmpstr(qom_tree_start, ==, qom_tree_end);
+#ifdef CONFIG_HMP
     qtree_end = qtest_hmp(qts, "info qtree");
     g_assert_cmpstr(qtree_start, ==, qtree_end);
+#endif
 
     qtest_quit(qts);
 }
@@ -217,18 +275,22 @@ static void test_device_intro_none(void)
 static void test_device_intro_abstract(void)
 {
     QTestState *qts = qtest_init(common_args);
-    g_autofree char *qom_tree_start = qtest_hmp(qts, "info qom-tree");
+    g_autofree char *qom_tree_start = qom_tree_str(qts);
     g_autofree char *qom_tree_end = NULL;
+#ifdef CONFIG_HMP
     g_autofree char *qtree_start = qtest_hmp(qts, "info qtree");
     g_autofree char *qtree_end = NULL;
+#endif
 
     test_one_device(qts, "device");
 
     /* Make sure that really nothing changed in the trees */
-    qom_tree_end = qtest_hmp(qts, "info qom-tree");
+    qom_tree_end = qom_tree_str(qts);
     g_assert_cmpstr(qom_tree_start, ==, qom_tree_end);
+#ifdef CONFIG_HMP
     qtree_end = qtest_hmp(qts, "info qtree");
     g_assert_cmpstr(qtree_start, ==, qtree_end);
+#endif
 
     qtest_quit(qts);
 }
@@ -239,10 +301,12 @@ static void test_device_intro_concrete(const void *args)
     QListEntry *entry;
     const char *type;
     QTestState *qts = qtest_init(args);
-    g_autofree char *qom_tree_start = qtest_hmp(qts, "info qom-tree");
+    g_autofree char *qom_tree_start = qom_tree_str(qts);
     g_autofree char *qom_tree_end = NULL;
+#ifdef CONFIG_HMP
     g_autofree char *qtree_start = qtest_hmp(qts, "info qtree");
     g_autofree char *qtree_end = NULL;
+#endif
 
     types = device_type_list(qts, false);
 
@@ -255,14 +319,15 @@ static void test_device_intro_concrete(const void *args)
 
     /*
      * Some devices leave dangling pointers in QOM behind.
-     * "info qom-tree" or "info qtree" have a good chance at crashing then.
+     * Walking the QOM tree via qom-list has a good chance at crashing then.
      * Also make sure that the tree did not change.
      */
-    qom_tree_end = qtest_hmp(qts, "info qom-tree");
+    qom_tree_end = qom_tree_str(qts);
     g_assert_cmpstr(qom_tree_start, ==, qom_tree_end);
-
+#ifdef CONFIG_HMP
     qtree_end = qtest_hmp(qts, "info qtree");
     g_assert_cmpstr(qtree_start, ==, qtree_end);
+#endif
 
     qobject_unref(types);
     qtest_quit(qts);

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 17/49] tests/qemu-iotests/205: fix race in assertExportNotFound
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (15 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 16/49] tests/qtest/device-introspect-test: fix test without HMP Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 18/49] net: add x-query-network QMP command Marc-André Lureau
                   ` (31 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Kevin Wolf,
	Hanna Reitz, qemu-block

After nbd-server-remove with mode=hard and an active client, the
export is removed from the NBD export list synchronously but remains
in the block export list until async cleanup completes (via
blk_exp_delete_bh bottom-half). A subsequent nbd-server-remove call
may find the export still in the block list with user_owned=false,
returning "already shutting down" instead of "not found".

Accept both error messages in assertExportNotFound, since both
indicate the export is no longer usable.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/qemu-iotests/205 | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/205 b/tests/qemu-iotests/205
index 2370e1a138b1..78459065418c 100755
--- a/tests/qemu-iotests/205
+++ b/tests/qemu-iotests/205
@@ -60,7 +60,9 @@ class TestNbdServerRemove(iotests.QMPTestCase):
 
     def assertExportNotFound(self, name):
         result = self.vm.qmp('nbd-server-remove', name=name)
-        self.assert_qmp(result, 'error/desc', "Export 'exp' is not found")
+        desc = result.get('error', {}).get('desc', '')
+        self.assertIn(desc, ("Export '%s' is not found" % name,
+                             "Export '%s' is already shutting down" % name))
 
     def assertExistingClients(self, result):
         self.assert_qmp(result, 'error/desc', "export 'exp' still in use")

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 18/49] net: add x-query-network QMP command
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (16 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 17/49] tests/qemu-iotests/205: fix race in assertExportNotFound Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 19/49] tests/qtest/netdev-socket: replace HMP with x-query-network QMP Marc-André Lureau
                   ` (30 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Jason Wang,
	Eric Blake

Add a structured x-query-network QMP command that returns network
configuration as a NetworkInfo struct with pre-grouped hub information
and a flat list of non-hub clients. Each hub includes its ports with
inlined peer client info, and each client includes attached netfilter
details.

Refactor hmp_info_network() to consume only the QMP result instead of
directly accessing internal net_clients state. This decouples HMP from
internal data structures, making it possible to remove HMP support
without losing programmatic network introspection.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/net/net.h  |   3 +-
 net/hub.c          |  29 +++++++------
 net/hub.h          |   4 +-
 net/net-hmp-cmds.c |  57 +++++++++++++++++++------
 net/net.c          |  70 +++++++++++++++++++++++-------
 qapi/net.json      | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 242 insertions(+), 43 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 9edfacf827ca..a7c49c543783 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -274,7 +274,6 @@ DeviceState *qemu_create_nic_device(const char *typename, bool match_default,
 void qemu_create_nic_bus_devices(BusState *bus, const char *parent_type,
                                  const char *default_model,
                                  const char *alias, const char *alias_target);
-void print_net_client(Monitor *mon, NetClientState *nc);
 void net_socket_rs_init(SocketReadState *rs,
                         SocketReadStateFinalize *finalize,
                         bool vnet_hdr);
@@ -325,6 +324,8 @@ void netdev_add(QemuOpts *opts, Error **errp);
 
 int net_hub_id_for_client(NetClientState *nc, int *id);
 
+NetworkClientInfo *net_client_info(NetClientState *nc);
+
 #define DEFAULT_NETWORK_SCRIPT CONFIG_SYSCONFDIR "/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT CONFIG_SYSCONFDIR "/qemu-ifdown"
 #define DEFAULT_BRIDGE_HELPER CONFIG_QEMU_HELPERDIR "/qemu-bridge-helper"
diff --git a/net/hub.c b/net/hub.c
index ee5881f6d5cb..b53a4cc872ca 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -14,7 +14,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "monitor/monitor.h"
+#include "qapi/util.h"
 #include "net/net.h"
 #include "clients.h"
 #include "hub.h"
@@ -199,26 +199,31 @@ NetClientState *net_hub_add_port(int hub_id, const char *name,
     return &port->nc;
 }
 
-/**
- * Print hub configuration
- */
-void net_hub_info(Monitor *mon)
+NetHubInfoList *net_hub_query_info(void)
 {
+    NetHubInfoList *head = NULL, **tail = &head;
     NetHub *hub;
-    NetHubPort *port;
 
     QLIST_FOREACH(hub, &hubs, next) {
-        monitor_printf(mon, "hub %d\n", hub->id);
+        NetHubInfo *hi = g_new0(NetHubInfo, 1);
+        NetHubPortInfoList **ptail = &hi->ports;
+        NetHubPort *port;
+
+        hi->id = hub->id;
+
         QLIST_FOREACH(port, &hub->ports, next) {
-            monitor_printf(mon, " \\ %s", port->nc.name);
+            NetHubPortInfo *pi = g_new0(NetHubPortInfo, 1);
+            pi->name = g_strdup(port->nc.name);
             if (port->nc.peer) {
-                monitor_printf(mon, ": ");
-                print_net_client(mon, port->nc.peer);
-            } else {
-                monitor_printf(mon, "\n");
+                pi->peer = net_client_info(port->nc.peer);
             }
+            QAPI_LIST_APPEND(ptail, pi);
         }
+
+        QAPI_LIST_APPEND(tail, hi);
     }
+
+    return head;
 }
 
 /**
diff --git a/net/hub.h b/net/hub.h
index ce45f7b399d3..cab6b1459b1a 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -15,10 +15,12 @@
 #ifndef NET_HUB_H
 #define NET_HUB_H
 
+#include "qapi/qapi-types-net.h"
+
 NetClientState *net_hub_add_port(int hub_id, const char *name,
                                  NetClientState *hubpeer);
-void net_hub_info(Monitor *mon);
 void net_hub_check_clients(void);
 bool net_hub_flush(NetClientState *nc);
+NetHubInfoList *net_hub_query_info(void);
 
 #endif /* NET_HUB_H */
diff --git a/net/net-hmp-cmds.c b/net/net-hmp-cmds.c
index 2b24c9e60498..52ac8da770d9 100644
--- a/net/net-hmp-cmds.c
+++ b/net/net-hmp-cmds.c
@@ -19,37 +19,66 @@
 #include "monitor/hmp-completion.h"
 #include "monitor/monitor.h"
 #include "net/net.h"
-#include "net/hub.h"
 #include "qapi/clone-visitor.h"
 #include "qapi/qapi-commands-net.h"
 #include "qapi/qapi-visit-net.h"
+#include "qapi/error.h"
 #include "qobject/qdict.h"
 #include "qemu/config-file.h"
 #include "qemu/help_option.h"
 #include "qemu/option.h"
 
+static void hmp_print_client_info(Monitor *mon, NetworkClientInfo *ci)
+{
+    NetFilterInfoList *f;
+
+    monitor_printf(mon, "%s: index=%" PRIu32 ",type=%s,%s\n",
+                   ci->name, ci->queue_index,
+                   NetClientDriver_str(ci->type), ci->info_str);
+    if (ci->filters) {
+        monitor_printf(mon, "filters:\n");
+        for (f = ci->filters; f; f = f->next) {
+            monitor_printf(mon, "  - %s: type=%s%s%s\n",
+                           f->value->name, f->value->type,
+                           f->value->info[0] ? "," : "", f->value->info);
+        }
+    }
+}
+
 void hmp_info_network(Monitor *mon, const QDict *qdict)
 {
-    NetClientState *nc, *peer;
-    NetClientDriver type;
+    Error *err = NULL;
+    g_autoptr(NetworkInfo) info = qmp_x_query_network(&err);
+    NetHubInfoList *h;
+    NetworkClientInfoList *entry;
 
-    net_hub_info(mon);
+    if (hmp_handle_error(mon, err)) {
+        return;
+    }
 
-    QTAILQ_FOREACH(nc, &net_clients, next) {
-        peer = nc->peer;
-        type = nc->info->type;
+    for (h = info->hubs; h; h = h->next) {
+        NetHubPortInfoList *p;
 
-        /* Skip if already printed in hub info */
-        if (net_hub_id_for_client(nc, NULL) == 0) {
-            continue;
+        monitor_printf(mon, "hub %d\n", (int)h->value->id);
+        for (p = h->value->ports; p; p = p->next) {
+            if (p->value->peer) {
+                monitor_printf(mon, " \\ %s: ", p->value->name);
+                hmp_print_client_info(mon, p->value->peer);
+            } else {
+                monitor_printf(mon, " \\ %s\n", p->value->name);
+            }
         }
+    }
 
-        if (!peer || type == NET_CLIENT_DRIVER_NIC) {
-            print_net_client(mon, nc);
+    for (entry = info->clients; entry; entry = entry->next) {
+        NetworkClientInfo *ci = entry->value;
+
+        if (!ci->peer || ci->type == NET_CLIENT_DRIVER_NIC) {
+            hmp_print_client_info(mon, ci);
         } /* else it's a netdev connected to a NIC, printed with the NIC */
-        if (peer && type == NET_CLIENT_DRIVER_NIC) {
+        if (ci->peer && ci->type == NET_CLIENT_DRIVER_NIC) {
             monitor_printf(mon, " \\ ");
-            print_net_client(mon, peer);
+            hmp_print_client_info(mon, ci->peer);
         }
     }
 }
diff --git a/net/net.c b/net/net.c
index 0a30579ca4a7..1161183e183d 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1525,14 +1525,14 @@ void qmp_netdev_del(const char *id, Error **errp)
     }
 }
 
-static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
+static char *netfilter_get_info_str(NetFilterState *nf)
 {
     char *str;
     ObjectProperty *prop;
     ObjectPropertyIterator iter;
     Visitor *v;
+    GString *buf = g_string_new(NULL);
 
-    /* generate info str */
     object_property_iter_init(&iter, OBJECT(nf));
     while ((prop = object_property_iter_next(&iter))) {
         if (!strcmp(prop->name, "type")) {
@@ -1542,29 +1542,69 @@ static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
         object_property_get(OBJECT(nf), prop->name, v, NULL);
         visit_complete(v, &str);
         visit_free(v);
-        monitor_printf(mon, ",%s=%s", prop->name, str);
+        if (buf->len > 0) {
+            g_string_append_c(buf, ',');
+        }
+        g_string_append_printf(buf, "%s=%s", prop->name, str);
         g_free(str);
     }
-    monitor_printf(mon, "\n");
+
+    return g_string_free(buf, false);
 }
 
-void print_net_client(Monitor *mon, NetClientState *nc)
+static NetworkClientInfo *net_client_info_no_peer(NetClientState *nc)
 {
+    NetworkClientInfo *info = g_new0(NetworkClientInfo, 1);
     NetFilterState *nf;
 
-    monitor_printf(mon, "%s: index=%d,type=%s,%s\n", nc->name,
-                   nc->queue_index,
-                   NetClientDriver_str(nc->info->type),
-                   nc->info_str);
+    info->name = g_strdup(nc->name);
+    info->queue_index = nc->queue_index;
+    info->type = nc->info->type;
+    info->info_str = g_strdup(nc->info_str);
+
     if (!QTAILQ_EMPTY(&nc->filters)) {
-        monitor_printf(mon, "filters:\n");
+        NetFilterInfoList **ftail = &info->filters;
+        QTAILQ_FOREACH(nf, &nc->filters, next) {
+            NetFilterInfo *fi = g_new0(NetFilterInfo, 1);
+            fi->name = g_strdup(
+                object_get_canonical_path_component(OBJECT(nf)));
+            fi->type = g_strdup(object_get_typename(OBJECT(nf)));
+            fi->info = netfilter_get_info_str(nf);
+            QAPI_LIST_APPEND(ftail, fi);
+        }
     }
-    QTAILQ_FOREACH(nf, &nc->filters, next) {
-        monitor_printf(mon, "  - %s: type=%s",
-                       object_get_canonical_path_component(OBJECT(nf)),
-                       object_get_typename(OBJECT(nf)));
-        netfilter_print_info(mon, nf);
+
+    return info;
+}
+
+NetworkClientInfo *net_client_info(NetClientState *nc)
+{
+    NetworkClientInfo *info = net_client_info_no_peer(nc);
+
+    if (nc->peer) {
+        info->peer = net_client_info_no_peer(nc->peer);
     }
+
+    return info;
+}
+
+NetworkInfo *qmp_x_query_network(Error **errp)
+{
+    NetworkInfo *info = g_new0(NetworkInfo, 1);
+    NetworkClientInfoList **tail = &info->clients;
+    NetClientState *nc;
+
+    info->hubs = net_hub_query_info();
+
+    QTAILQ_FOREACH(nc, &net_clients, next) {
+        /* Skip if already gathered in hub info */
+        if (net_hub_id_for_client(nc, NULL) == 0) {
+            continue;
+        }
+        QAPI_LIST_APPEND(tail, net_client_info(nc));
+    }
+
+    return info;
 }
 
 RxFilterInfoList *qmp_query_rx_filter(const char *name, Error **errp)
diff --git a/qapi/net.json b/qapi/net.json
index 5d3342fba23b..85c78710fe88 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -1305,3 +1305,125 @@
   'returns': ['UsernetInfo'],
   'if': 'CONFIG_SLIRP',
   'features': [ 'unstable' ] }
+
+##
+# @NetFilterInfo:
+#
+# Information about a netfilter attached to a network client.
+#
+# @name: filter object name (QOM path component)
+#
+# @type: QOM type name (e.g. "filter-mirror")
+#
+# @info: filter properties as comma-separated key=value pairs
+#        (excluding @type)
+#
+# Since: 11.2
+##
+{ 'struct': 'NetFilterInfo',
+  'data': {
+    'name': 'str',
+    'type': 'str',
+    'info': 'str' } }
+
+##
+# @NetworkClientInfo:
+#
+# Information about a network client.
+#
+# @name: unique network client identifier
+#
+# @queue-index: index of this queue (0 for single-queue clients)
+#
+# @type: network client driver type
+#
+# @info-str: driver-specific formatted information string (e.g.
+#            "model=e1000,macaddr=52:54:00:12:34:56")
+#
+# @peer: the connected peer client (always a leaf; the peer's own
+#        peer field is never populated)
+#
+# @filters: attached netfilters
+#
+# Since: 11.2
+##
+{ 'struct': 'NetworkClientInfo',
+  'data': {
+    'name': 'str',
+    'queue-index': 'uint32',
+    'type': 'NetClientDriver',
+    'info-str': 'str',
+    '*peer': 'NetworkClientInfo',
+    'filters': ['NetFilterInfo'] } }
+
+##
+# @NetHubPortInfo:
+#
+# Information about a hub port.
+#
+# @name: hub port identifier
+#
+# @peer: the network client connected through this port
+#
+# Since: 11.2
+##
+{ 'struct': 'NetHubPortInfo',
+  'data': {
+    'name': 'str',
+    '*peer': 'NetworkClientInfo' } }
+
+##
+# @NetHubInfo:
+#
+# Information about a network hub.
+#
+# @id: hub identifier
+#
+# @ports: list of ports on this hub
+#
+# Since: 11.2
+##
+{ 'struct': 'NetHubInfo',
+  'data': {
+    'id': 'int',
+    'ports': ['NetHubPortInfo'] } }
+
+##
+# @NetworkInfo:
+#
+# Information about the network configuration.
+#
+# @hubs: network hubs and their ports
+#
+# @clients: network clients not associated with a hub
+#
+# Since: 11.2
+##
+{ 'struct': 'NetworkInfo',
+  'data': {
+    'hubs': ['NetHubInfo'],
+    'clients': ['NetworkClientInfo'] } }
+
+##
+# @x-query-network:
+#
+# Query the network configuration including hubs and clients.
+#
+# Features:
+#
+# @unstable: This command is meant for debugging.
+#
+# Returns: @NetworkInfo describing hubs and clients.
+#
+# Since: 11.2
+#
+# .. qmp-example::
+#
+#     -> { "execute": "x-query-network" }
+#     <- { "return": { "clients": [ { "name": "st0",
+#                      "queue-index": 0, "type": "stream",
+#                      "info-str": "listening" } ] } }
+##
+{ 'command': 'x-query-network',
+  'returns': 'NetworkInfo',
+  'features': [ 'unstable' ] }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 19/49] tests/qtest/netdev-socket: replace HMP with x-query-network QMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (17 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 18/49] net: add x-query-network QMP command Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 20/49] qemu-io: propagate errors through Error API instead of printf Marc-André Lureau
                   ` (29 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Fabiano Rosas,
	Laurent Vivier, Paolo Bonzini

Replace the HMP "info network" text parsing with the structured
x-query-network QMP command. This makes the test assertions more robust
by matching individual fields (info-str) instead of parsing the full HMP
line format.

The EXPECT_STATE macro now takes an explicit netdev id argument to look
up the client by name in the QMP response. The strrchr truncation is
made NULL-safe: if the truncation character is not found, the full
string is compared (and the final g_assert_cmpstr will catch
mismatches).

While at it, fix the pre-existing duplicate "qemu/sockets.h" include,
and reorder includes.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/qtest/netdev-socket.c | 143 +++++++++++++++++++++++++-------------------
 1 file changed, 82 insertions(+), 61 deletions(-)

diff --git a/tests/qtest/netdev-socket.c b/tests/qtest/netdev-socket.c
index b731af0ad959..30005c2e0015 100644
--- a/tests/qtest/netdev-socket.c
+++ b/tests/qtest/netdev-socket.c
@@ -7,33 +7,62 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu/sockets.h"
 #include <glib/gstdio.h>
 #include "../unit/socket-helpers.h"
 #include "libqtest.h"
-#include "qobject/qstring.h"
-#include "qemu/sockets.h"
-#include "qapi/qobject-input-visitor.h"
 #include "qapi/qapi-visit-sockets.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qemu/sockets.h"
+#include "qobject/qdict.h"
+#include "qobject/qlist.h"
+#include "qobject/qstring.h"
 
 #define CONNECTION_TIMEOUT    60
 
-#define EXPECT_STATE(q, e, t)                             \
-do {                                                      \
-    char *resp = NULL;                                    \
-    g_test_timer_start();                                 \
-    do {                                                  \
-        g_free(resp);                                     \
-        resp = qtest_hmp(q, "info network");              \
-        if (t) {                                          \
-            strrchr(resp, t)[0] = 0;                      \
-        }                                                 \
-        if (g_str_equal(resp, e)) {                       \
-            break;                                        \
-        }                                                 \
-    } while (g_test_timer_elapsed() < CONNECTION_TIMEOUT); \
-    g_assert_cmpstr(resp, ==, e);                         \
-    g_free(resp);                                         \
+/*
+ * Only checks info-str; type is implicit from the netdev created by each test
+ */
+static char *query_net_info_str(QTestState *q, const char *name)
+{
+    QDict *ret;
+    QList *clients;
+    QListEntry *entry;
+
+    ret = qtest_qmp_assert_success_ref(q, "{'execute': 'x-query-network'}");
+    clients = qdict_get_qlist(ret, "clients");
+    g_assert_nonnull(clients);
+
+    QLIST_FOREACH_ENTRY(clients, entry) {
+        QDict *client = qobject_to(QDict, qlist_entry_obj(entry));
+        if (g_str_equal(qdict_get_str(client, "name"), name)) {
+            char *info = g_strdup(qdict_get_str(client, "info-str"));
+            qobject_unref(ret);
+            return info;
+        }
+    }
+
+    g_assert_not_reached();
+}
+
+#define EXPECT_STATE(q, id, e, t)                           \
+do {                                                        \
+    char *info = NULL;                                      \
+    g_test_timer_start();                                   \
+    do {                                                    \
+        g_free(info);                                       \
+        info = query_net_info_str(q, id);                   \
+        if (t) {                                            \
+            char *p = strrchr(info, t);                     \
+            if (p) {                                        \
+                p[0] = 0;                                   \
+            }                                               \
+        }                                                   \
+        if (g_str_equal(info, e)) {                         \
+            break;                                          \
+        }                                                   \
+    } while (g_test_timer_elapsed() < CONNECTION_TIMEOUT);  \
+    g_assert_cmpstr(info, ==, e);                           \
+    g_free(info);                                           \
 } while (0)
 
 static gchar *tmpdir;
@@ -127,20 +156,19 @@ static void test_stream_inet_ipv4(void)
                        "addr.ipv4=on,addr.ipv6=off,"
                        "addr.host=127.0.0.1,addr.port=%d", port);
 
-    EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);
+    EXPECT_STATE(qts0, "st0", "listening", 0);
 
     qts1 = qtest_initf("-nodefaults -M none "
                        "-netdev stream,server=false,id=st0,addr.type=inet,"
                        "addr.ipv4=on,addr.ipv6=off,"
                        "addr.host=127.0.0.1,addr.port=%d", port);
 
-    expect = g_strdup_printf("st0: index=0,type=stream,tcp:127.0.0.1:%d\r\n",
-                             port);
-    EXPECT_STATE(qts1, expect, 0);
+    expect = g_strdup_printf("tcp:127.0.0.1:%d", port);
+    EXPECT_STATE(qts1, "st0", expect, 0);
     g_free(expect);
 
     /* the port is unknown, check only the address */
-    EXPECT_STATE(qts0, "st0: index=0,type=stream,tcp:127.0.0.1", ':');
+    EXPECT_STATE(qts0, "st0", "tcp:127.0.0.1", ':');
 
     qtest_quit(qts1);
     qtest_quit(qts0);
@@ -200,7 +228,7 @@ static void test_stream_unix_reconnect(void)
                        "-netdev stream,id=st0,server=true,addr.type=unix,"
                        "addr.path=%s", path);
 
-    EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);
+    EXPECT_STATE(qts0, "st0", "listening", 0);
 
     qts1 = qtest_initf("-nodefaults -M none "
                        "-netdev stream,server=false,id=st0,addr.type=unix,"
@@ -250,20 +278,19 @@ static void test_stream_inet_ipv6(void)
                        "addr.ipv4=off,addr.ipv6=on,"
                        "addr.host=::1,addr.port=%d", port);
 
-    EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);
+    EXPECT_STATE(qts0, "st0", "listening", 0);
 
     qts1 = qtest_initf("-nodefaults -M none "
                        "-netdev stream,server=false,id=st0,addr.type=inet,"
                        "addr.ipv4=off,addr.ipv6=on,"
                        "addr.host=::1,addr.port=%d", port);
 
-    expect = g_strdup_printf("st0: index=0,type=stream,tcp:::1:%d\r\n",
-                             port);
-    EXPECT_STATE(qts1, expect, 0);
+    expect = g_strdup_printf("tcp:::1:%d", port);
+    EXPECT_STATE(qts1, "st0", expect, 0);
     g_free(expect);
 
     /* the port is unknown, check only the address */
-    EXPECT_STATE(qts0, "st0: index=0,type=stream,tcp:::1", ':');
+    EXPECT_STATE(qts0, "st0", "tcp:::1", ':');
 
     qtest_quit(qts1);
     qtest_quit(qts0);
@@ -282,16 +309,16 @@ static void test_stream_unix(void)
                        "addr.type=unix,addr.path=%s,",
                        path);
 
-    EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);
+    EXPECT_STATE(qts0, "st0", "listening", 0);
 
     qts1 = qtest_initf("-nodefaults -M none "
                        "-netdev stream,id=st0,server=false,"
                        "addr.type=unix,addr.path=%s",
                        path);
 
-    expect = g_strdup_printf("st0: index=0,type=stream,unix:%s\r\n", path);
-    EXPECT_STATE(qts1, expect, 0);
-    EXPECT_STATE(qts0, expect, 0);
+    expect = g_strdup_printf("unix:%s", path);
+    EXPECT_STATE(qts1, "st0", expect, 0);
+    EXPECT_STATE(qts0, "st0", expect, 0);
     g_free(expect);
     g_free(path);
 
@@ -314,16 +341,16 @@ static void test_stream_unix_abstract(void)
                        "addr.abstract=on",
                        path);
 
-    EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);
+    EXPECT_STATE(qts0, "st0", "listening", 0);
 
     qts1 = qtest_initf("-nodefaults -M none "
                        "-netdev stream,id=st0,server=false,"
                        "addr.type=unix,addr.path=%s,addr.abstract=on",
                        path);
 
-    expect = g_strdup_printf("st0: index=0,type=stream,unix:%s\r\n", path);
-    EXPECT_STATE(qts1, expect, 0);
-    EXPECT_STATE(qts0, expect, 0);
+    expect = g_strdup_printf("unix:%s", path);
+    EXPECT_STATE(qts1, "st0", expect, 0);
+    EXPECT_STATE(qts0, "st0", expect, 0);
     g_free(expect);
     g_free(path);
 
@@ -346,14 +373,14 @@ static void test_stream_fd(void)
                        "-netdev stream,id=st0,addr.type=fd,addr.str=%d",
                        sock[0]);
 
-    EXPECT_STATE(qts0, "st0: index=0,type=stream,unix:\r\n", 0);
+    EXPECT_STATE(qts0, "st0", "unix:", 0);
 
     qts1 = qtest_initf("-nodefaults -M none "
                        "-netdev stream,id=st0,addr.type=fd,addr.str=%d",
                        sock[1]);
 
-    EXPECT_STATE(qts1, "st0: index=0,type=stream,unix:\r\n", 0);
-    EXPECT_STATE(qts0, "st0: index=0,type=stream,unix:\r\n", 0);
+    EXPECT_STATE(qts1, "st0", "unix:", 0);
+    EXPECT_STATE(qts0, "st0", "unix:", 0);
 
     qtest_quit(qts1);
     qtest_quit(qts0);
@@ -379,10 +406,9 @@ static void test_dgram_inet(void)
                        "remote.type=inet,remote.host=127.0.0.1,remote.port=%d",
                         port[0], port[1]);
 
-    expect = g_strdup_printf("st0: index=0,type=dgram,"
-                             "udp=127.0.0.1:%d/127.0.0.1:%d\r\n",
+    expect = g_strdup_printf("udp=127.0.0.1:%d/127.0.0.1:%d",
                              port[0], port[1]);
-    EXPECT_STATE(qts0, expect, 0);
+    EXPECT_STATE(qts0, "st0", expect, 0);
     g_free(expect);
 
     qts1 = qtest_initf("-nodefaults -M none "
@@ -391,10 +417,9 @@ static void test_dgram_inet(void)
                        "remote.type=inet,remote.host=127.0.0.1,remote.port=%d",
                         port[1], port[0]);
 
-    expect = g_strdup_printf("st0: index=0,type=dgram,"
-                             "udp=127.0.0.1:%d/127.0.0.1:%d\r\n",
+    expect = g_strdup_printf("udp=127.0.0.1:%d/127.0.0.1:%d",
                              port[1], port[0]);
-    EXPECT_STATE(qts1, expect, 0);
+    EXPECT_STATE(qts1, "st0", expect, 0);
     g_free(expect);
 
     qtest_quit(qts1);
@@ -410,7 +435,7 @@ static void test_dgram_mcast(void)
                       "-netdev dgram,id=st0,"
                       "remote.type=inet,remote.host=230.0.0.1,remote.port=1234");
 
-    EXPECT_STATE(qts, "st0: index=0,type=dgram,mcast=230.0.0.1:1234\r\n", 0);
+    EXPECT_STATE(qts, "st0", "mcast=230.0.0.1:1234", 0);
 
     qtest_quit(qts);
 }
@@ -431,9 +456,8 @@ static void test_dgram_unix(void)
                        "remote.type=unix,remote.path=%s",
                        path0, path1);
 
-    expect = g_strdup_printf("st0: index=0,type=dgram,udp=%s:%s\r\n",
-                             path0, path1);
-    EXPECT_STATE(qts0, expect, 0);
+    expect = g_strdup_printf("udp=%s:%s", path0, path1);
+    EXPECT_STATE(qts0, "st0", expect, 0);
     g_free(expect);
 
     qts1 = qtest_initf("-nodefaults -M none "
@@ -441,10 +465,8 @@ static void test_dgram_unix(void)
                        "remote.type=unix,remote.path=%s",
                        path1, path0);
 
-
-    expect = g_strdup_printf("st0: index=0,type=dgram,udp=%s:%s\r\n",
-                             path1, path0);
-    EXPECT_STATE(qts1, expect, 0);
+    expect = g_strdup_printf("udp=%s:%s", path1, path0);
+    EXPECT_STATE(qts1, "st0", expect, 0);
     g_free(expect);
 
     unlink(path0);
@@ -470,17 +492,16 @@ static void test_dgram_fd(void)
                        "-netdev dgram,id=st0,local.type=fd,local.str=%d",
                        sv[0]);
 
-    expect = g_strdup_printf("st0: index=0,type=dgram,fd=%d unix\r\n", sv[0]);
-    EXPECT_STATE(qts0, expect, 0);
+    expect = g_strdup_printf("fd=%d unix", sv[0]);
+    EXPECT_STATE(qts0, "st0", expect, 0);
     g_free(expect);
 
     qts1 = qtest_initf("-nodefaults -M none "
                        "-netdev dgram,id=st0,local.type=fd,local.str=%d",
                        sv[1]);
 
-
-    expect = g_strdup_printf("st0: index=0,type=dgram,fd=%d unix\r\n", sv[1]);
-    EXPECT_STATE(qts1, expect, 0);
+    expect = g_strdup_printf("fd=%d unix", sv[1]);
+    EXPECT_STATE(qts1, "st0", expect, 0);
     g_free(expect);
 
     qtest_quit(qts1);

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 20/49] qemu-io: propagate errors through Error API instead of printf
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (18 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 19/49] tests/qtest/netdev-socket: replace HMP with x-query-network QMP Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 21/49] block: add x-qemu-io QMP command Marc-André Lureau
                   ` (28 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Kevin Wolf,
	Hanna Reitz, Eric Blake, Vladimir Sementsov-Ogievskiy, qemu-block,
	Philippe Mathieu-Daudé

Convert the qemu-io command infrastructure to use QEMU's Error API
(Error **errp) for error propagation instead of printing directly to
stdout/stderr via printf/fprintf.

The cfunc_t typedef, all ~35 command functions, the dispatcher chain
(command/init_check_command/qemuio_command), and helper functions
(parse_pattern, create_iovec, qemu_io_alloc_from_file) all gain an
Error **errp parameter. Async completion callbacks (aio_read_done,
aio_write_done, aio_discard_done) use error_report() since they have
no Error path back to the caller.

Update tests:
- error_report_err() prepends qemu-io: prefix
- copy-before-write: check the HMP return value, rather than stdio
- other tests: update to check JSON {"return": "Error: error text"}

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 block/monitor/block-hmp-cmds.c                 |   2 +-
 include/qemu-io.h                              |   4 +-
 qemu-io-cmds.c                                 | 414 +++++++++++++------------
 qemu-io.c                                      |  17 +-
 tests/qemu-iotests/004.out                     |  20 +-
 tests/qemu-iotests/021.out                     |  60 ++--
 tests/qemu-iotests/026.out                     | 228 +++++++-------
 tests/qemu-iotests/060.out                     |  44 ++-
 tests/qemu-iotests/071.out                     |  10 +-
 tests/qemu-iotests/072.out                     |   2 +-
 tests/qemu-iotests/080.out                     |   4 +-
 tests/qemu-iotests/081.out                     |   2 +-
 tests/qemu-iotests/083.out                     |  36 +--
 tests/qemu-iotests/089.out                     |   4 +-
 tests/qemu-iotests/114.out                     |   2 +-
 tests/qemu-iotests/134.out                     |   2 +-
 tests/qemu-iotests/137.out                     |   2 +-
 tests/qemu-iotests/153.out                     |  12 +-
 tests/qemu-iotests/171                         |   2 +-
 tests/qemu-iotests/171.out                     |  68 ++--
 tests/qemu-iotests/205                         |   2 +-
 tests/qemu-iotests/214.out                     |   2 +-
 tests/qemu-iotests/220.out                     |   2 +-
 tests/qemu-iotests/225.out                     |   4 +-
 tests/qemu-iotests/244.out                     |  12 +-
 tests/qemu-iotests/249.out                     |   6 +-
 tests/qemu-iotests/271.out                     |  14 +-
 tests/qemu-iotests/289.out                     |   2 +-
 tests/qemu-iotests/305.out                     |   2 +-
 tests/qemu-iotests/307.out                     |   2 +-
 tests/qemu-iotests/tests/backup-discard-source |   4 +-
 tests/qemu-iotests/tests/copy-before-write     |  66 ++--
 tests/qemu-iotests/tests/file-io-error.out     |   2 +-
 tests/qemu-iotests/tests/image-fleecing.out    |  12 +-
 tests/qemu-iotests/tests/inactive-node-nbd.out |   8 +-
 35 files changed, 552 insertions(+), 523 deletions(-)

diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index 39b82e8ef501..9930620a4a16 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -598,7 +598,7 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
      * extended, possibly resulting in a read-only guest device keeping write
      * permissions. Ugly, but it appears to be the lesser evil.
      */
-    qemuio_command(blk, command);
+    qemuio_command(blk, command, &err);
 
 fail:
     blk_unref(local_blk);
diff --git a/include/qemu-io.h b/include/qemu-io.h
index 3af513004a68..240764bb35cd 100644
--- a/include/qemu-io.h
+++ b/include/qemu-io.h
@@ -25,7 +25,7 @@
  * Operate on @blk using @argc/@argv as the command's arguments, and
  * return 0 on success or negative errno on failure.
  */
-typedef int (*cfunc_t)(BlockBackend *blk, int argc, char **argv);
+typedef int (*cfunc_t)(BlockBackend *blk, int argc, char **argv, Error **errp);
 
 typedef void (*helpfunc_t)(void);
 
@@ -45,7 +45,7 @@ typedef struct cmdinfo {
 
 extern bool qemuio_misalign;
 
-int qemuio_command(BlockBackend *blk, const char *cmd);
+int qemuio_command(BlockBackend *blk, const char *cmd, Error **errp);
 
 void qemuio_add_command(const cmdinfo_t *ci);
 void qemuio_command_usage(const cmdinfo_t *ci);
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index de4c1966feae..aa795fd87a14 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -55,40 +55,43 @@ void qemuio_command_usage(const cmdinfo_t *ci)
     printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline);
 }
 
-static int init_check_command(BlockBackend *blk, const cmdinfo_t *ct)
+static int init_check_command(BlockBackend *blk, const cmdinfo_t *ct,
+                              Error **errp)
 {
     if (ct->flags & CMD_FLAG_GLOBAL) {
         return 1;
     }
     if (!(ct->flags & CMD_NOFILE_OK) && !blk) {
-        fprintf(stderr, "no file open, try 'help open'\n");
+        error_setg(errp, "no file open, try 'help open'");
         return 0;
     }
     return 1;
 }
 
 static int command(BlockBackend *blk, const cmdinfo_t *ct, int argc,
-                   char **argv)
+                   char **argv, Error **errp)
 {
     char *cmd = argv[0];
 
-    if (!init_check_command(blk, ct)) {
+    if (!init_check_command(blk, ct, errp)) {
         return -EINVAL;
     }
 
     if (argc - 1 < ct->argmin || (ct->argmax != -1 && argc - 1 > ct->argmax)) {
         if (ct->argmax == -1) {
-            fprintf(stderr,
-                    "bad argument count %d to %s, expected at least %d arguments\n",
-                    argc-1, cmd, ct->argmin);
+            error_setg(errp,
+                       "bad argument count %d to %s,"
+                       " expected at least %d arguments",
+                       argc - 1, cmd, ct->argmin);
         } else if (ct->argmin == ct->argmax) {
-            fprintf(stderr,
-                    "bad argument count %d to %s, expected %d arguments\n",
-                    argc-1, cmd, ct->argmin);
+            error_setg(errp,
+                       "bad argument count %d to %s, expected %d arguments",
+                       argc - 1, cmd, ct->argmin);
         } else {
-            fprintf(stderr,
-                    "bad argument count %d to %s, expected between %d and %d arguments\n",
-                    argc-1, cmd, ct->argmin, ct->argmax);
+            error_setg(errp,
+                       "bad argument count %d to %s,"
+                       " expected between %d and %d arguments",
+                       argc - 1, cmd, ct->argmin, ct->argmax);
         }
         return -EINVAL;
     }
@@ -112,21 +115,19 @@ static int command(BlockBackend *blk, const cmdinfo_t *ct, int argc,
 
         if (ct->perm & ~orig_perm) {
             uint64_t new_perm;
-            Error *local_err = NULL;
             int ret;
 
             new_perm = orig_perm | ct->perm;
 
-            ret = blk_set_perm(blk, new_perm, orig_shared_perm, &local_err);
+            ret = blk_set_perm(blk, new_perm, orig_shared_perm, errp);
             if (ret < 0) {
-                error_report_err(local_err);
                 return ret;
             }
         }
     }
 
     qemu_reset_optind();
-    return ct->cfunc(blk, argc, argv);
+    return ct->cfunc(blk, argc, argv, errp);
 }
 
 static const cmdinfo_t *find_command(const char *cmd)
@@ -192,18 +193,18 @@ static int64_t cvtnum(const char *s)
     return value;
 }
 
-static void print_cvtnum_err(int64_t rc, const char *arg)
+static void set_cvtnum_err(int64_t rc, const char *arg, Error **errp)
 {
     switch (rc) {
     case -EINVAL:
-        printf("Parsing error: non-numeric argument,"
-               " or extraneous/unrecognized suffix -- %s\n", arg);
+        error_setg(errp, "Parsing error: non-numeric argument,"
+                   " or extraneous/unrecognized suffix -- %s", arg);
         break;
     case -ERANGE:
-        printf("Parsing error: argument too large -- %s\n", arg);
+        error_setg(errp, "Parsing error: argument too large -- %s", arg);
         break;
     default:
-        printf("Parsing error: %s\n", arg);
+        error_setg(errp, "Parsing error: %s", arg);
     }
 }
 
@@ -316,14 +317,14 @@ static void timestr(struct timespec *tv, char *ts, size_t size, int format)
  * Because the pattern is used as an argument to memset it must evaluate
  * to an unsigned integer that fits into a single byte.
  */
-static int parse_pattern(const char *arg)
+static int parse_pattern(const char *arg, Error **errp)
 {
     char *endptr = NULL;
     long pattern;
 
     pattern = strtol(arg, &endptr, 0);
     if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
-        printf("%s is not a valid pattern byte\n", arg);
+        error_setg(errp, "%s is not a valid pattern byte", arg);
         return -1;
     }
 
@@ -386,7 +387,8 @@ static void qemu_io_free(BlockBackend *blk, void *p, size_t len,
  *          NULL on error
  */
 static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
-                                     const char *file_name, bool register_buf)
+                                     const char *file_name, bool register_buf,
+                                     Error **errp)
 {
     size_t alloc_len = len + (qemuio_misalign ? MISALIGN_OFFSET : 0);
     char *alloc_buf, *buf, *end;
@@ -394,7 +396,7 @@ static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
     int pattern_len;
 
     if (!f) {
-        perror(file_name);
+        error_setg_errno(errp, errno, "%s", file_name);
         return NULL;
     }
 
@@ -407,12 +409,12 @@ static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
     pattern_len = fread(buf, 1, len, f);
 
     if (ferror(f)) {
-        perror(file_name);
+        error_setg_errno(errp, errno, "%s", file_name);
         goto error;
     }
 
     if (pattern_len == 0) {
-        fprintf(stderr, "%s: file is empty\n", file_name);
+        error_setg(errp, "%s: file is empty", file_name);
         goto error;
     }
 
@@ -494,7 +496,7 @@ static void print_report(const char *op, struct timespec *t, int64_t offset,
  */
 static void *
 create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov,
-             int pattern, bool register_buf)
+             int pattern, bool register_buf, Error **errp)
 {
     size_t *sizes = g_new0(size_t, nr_iov);
     size_t count = 0;
@@ -508,19 +510,20 @@ create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov,
 
         len = cvtnum(arg);
         if (len < 0) {
-            print_cvtnum_err(len, arg);
+            set_cvtnum_err(len, arg, errp);
             goto fail;
         }
 
         if (len > BDRV_REQUEST_MAX_BYTES) {
-            printf("Argument '%s' exceeds maximum size %" PRIu64 "\n", arg,
-                   (uint64_t)BDRV_REQUEST_MAX_BYTES);
+            error_setg(errp, "Argument '%s' exceeds maximum size %" PRIu64,
+                       arg, (uint64_t)BDRV_REQUEST_MAX_BYTES);
             goto fail;
         }
 
         if (count > BDRV_REQUEST_MAX_BYTES - len) {
-            printf("The total number of bytes exceed the maximum size %" PRIu64
-                   "\n", (uint64_t)BDRV_REQUEST_MAX_BYTES);
+            error_setg(errp,
+                       "The total number of bytes exceed the maximum size %"
+                       PRIu64, (uint64_t)BDRV_REQUEST_MAX_BYTES);
             goto fail;
         }
 
@@ -692,7 +695,7 @@ static void read_help(void)
 "\n");
 }
 
-static int read_f(BlockBackend *blk, int argc, char **argv);
+static int read_f(BlockBackend *blk, int argc, char **argv, Error **errp);
 
 static const cmdinfo_t read_cmd = {
     .name       = "read",
@@ -705,7 +708,7 @@ static const cmdinfo_t read_cmd = {
     .help       = read_help,
 };
 
-static int read_f(BlockBackend *blk, int argc, char **argv)
+static int read_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     struct timespec t1, t2;
     bool Cflag = false, qflag = false, vflag = false;
@@ -732,7 +735,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
             lflag = true;
             pattern_count = cvtnum(optarg);
             if (pattern_count < 0) {
-                print_cvtnum_err(pattern_count, optarg);
+                set_cvtnum_err(pattern_count, optarg, errp);
                 return pattern_count;
             }
             break;
@@ -741,7 +744,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
             break;
         case 'P':
             Pflag = true;
-            pattern = parse_pattern(optarg);
+            pattern = parse_pattern(optarg, errp);
             if (pattern < 0) {
                 return -EINVAL;
             }
@@ -756,7 +759,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
             sflag = true;
             pattern_offset = cvtnum(optarg);
             if (pattern_offset < 0) {
-                print_cvtnum_err(pattern_offset, optarg);
+                set_cvtnum_err(pattern_offset, optarg, errp);
                 return pattern_offset;
             }
             break;
@@ -776,18 +779,18 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
 
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[optind]);
+        set_cvtnum_err(offset, argv[optind], errp);
         return offset;
     }
 
     optind++;
     count = cvtnum(argv[optind]);
     if (count < 0) {
-        print_cvtnum_err(count, argv[optind]);
+        set_cvtnum_err(count, argv[optind], errp);
         return count;
     } else if (count > BDRV_REQUEST_MAX_BYTES) {
-        printf("length cannot exceed %" PRIu64 ", given %s\n",
-               (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
+        error_setg(errp, "length cannot exceed %" PRIu64 ", given %s",
+                   (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
         return -EINVAL;
     }
 
@@ -801,24 +804,26 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
     }
 
     if ((pattern_count < 0) || (pattern_count + pattern_offset > count))  {
-        printf("pattern verification range exceeds end of read data\n");
+        error_setg(errp, "pattern verification range exceeds end of read data");
         return -EINVAL;
     }
 
     if (bflag) {
         if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
-            printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
-                   offset);
+            error_setg(errp,
+                       "%" PRId64 " is not a sector-aligned value for 'offset'",
+                       offset);
             return -EINVAL;
         }
         if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
-            printf("%"PRId64" is not a sector-aligned value for 'count'\n",
-                   count);
+            error_setg(errp,
+                       "%" PRId64 " is not a sector-aligned value for 'count'",
+                       count);
             return -EINVAL;
         }
         if (flags & BDRV_REQ_REGISTERED_BUF) {
-            printf("I/O buffer registration is not supported when reading "
-                    "from vmstate\n");
+            error_setg(errp, "I/O buffer registration is not supported when"
+                       " reading from vmstate");
             return -EINVAL;
         }
     }
@@ -834,7 +839,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
     clock_gettime(CLOCK_MONOTONIC, &t2);
 
     if (ret < 0) {
-        printf("read failed: %s\n", strerror(-ret));
+        error_setg(errp, "read failed: %s", strerror(-ret));
         goto out;
     }
     cnt = ret;
@@ -845,9 +850,9 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
         void *cmp_buf = g_malloc(pattern_count);
         memset(cmp_buf, pattern, pattern_count);
         if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
-            printf("Pattern verification failed at offset %"
-                   PRId64 ", %"PRId64" bytes\n",
-                   offset + pattern_offset, pattern_count);
+            error_setg(errp, "Pattern verification failed at offset %"
+                       PRId64 ", %" PRId64 " bytes",
+                       offset + pattern_offset, pattern_count);
             ret = -EINVAL;
         }
         g_free(cmp_buf);
@@ -890,7 +895,7 @@ static void readv_help(void)
 "\n");
 }
 
-static int readv_f(BlockBackend *blk, int argc, char **argv);
+static int readv_f(BlockBackend *blk, int argc, char **argv, Error **errp);
 
 static const cmdinfo_t readv_cmd = {
     .name       = "readv",
@@ -902,7 +907,7 @@ static const cmdinfo_t readv_cmd = {
     .help       = readv_help,
 };
 
-static int readv_f(BlockBackend *blk, int argc, char **argv)
+static int readv_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     struct timespec t1, t2;
     bool Cflag = false, qflag = false, vflag = false;
@@ -924,7 +929,7 @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
             break;
         case 'P':
             Pflag = true;
-            pattern = parse_pattern(optarg);
+            pattern = parse_pattern(optarg, errp);
             if (pattern < 0) {
                 return -EINVAL;
             }
@@ -952,14 +957,14 @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
 
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[optind]);
+        set_cvtnum_err(offset, argv[optind], errp);
         return offset;
     }
     optind++;
 
     nr_iov = argc - optind;
     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, 0xab,
-                       flags & BDRV_REQ_REGISTERED_BUF);
+                       flags & BDRV_REQ_REGISTERED_BUF, errp);
     if (buf == NULL) {
         return -EINVAL;
     }
@@ -969,7 +974,7 @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
     clock_gettime(CLOCK_MONOTONIC, &t2);
 
     if (ret < 0) {
-        printf("readv failed: %s\n", strerror(-ret));
+        error_setg(errp, "readv failed: %s", strerror(-ret));
         goto out;
     }
     cnt = ret;
@@ -980,8 +985,8 @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
         void *cmp_buf = g_malloc(qiov.size);
         memset(cmp_buf, pattern, qiov.size);
         if (memcmp(buf, cmp_buf, qiov.size)) {
-            printf("Pattern verification failed at offset %"
-                   PRId64 ", %zu bytes\n", offset, qiov.size);
+            error_setg(errp, "Pattern verification failed at offset %"
+                       PRId64 ", %zu bytes", offset, qiov.size);
             ret = -EINVAL;
         }
         g_free(cmp_buf);
@@ -1031,7 +1036,7 @@ static void write_help(void)
 "\n");
 }
 
-static int write_f(BlockBackend *blk, int argc, char **argv);
+static int write_f(BlockBackend *blk, int argc, char **argv, Error **errp);
 
 static const cmdinfo_t write_cmd = {
     .name       = "write",
@@ -1045,7 +1050,7 @@ static const cmdinfo_t write_cmd = {
     .help       = write_help,
 };
 
-static int write_f(BlockBackend *blk, int argc, char **argv)
+static int write_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     struct timespec t1, t2;
     bool Cflag = false, qflag = false, bflag = false;
@@ -1082,7 +1087,7 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
             break;
         case 'P':
             Pflag = true;
-            pattern = parse_pattern(optarg);
+            pattern = parse_pattern(optarg, errp);
             if (pattern < 0) {
                 return -EINVAL;
             }
@@ -1115,72 +1120,78 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
     }
 
     if (bflag && zflag) {
-        printf("-b and -z cannot be specified at the same time\n");
+        error_setg(errp, "-b and -z cannot be specified at the same time");
         return -EINVAL;
     }
 
     if ((flags & BDRV_REQ_FUA) && (bflag || cflag)) {
-        printf("-f and -b or -c cannot be specified at the same time\n");
+        error_setg(errp,
+                   "-f and -b or -c cannot be specified at the same time");
         return -EINVAL;
     }
 
     if ((flags & BDRV_REQ_NO_FALLBACK) && !zflag) {
-        printf("-n requires -z to be specified\n");
+        error_setg(errp, "-n requires -z to be specified");
         return -EINVAL;
     }
 
     if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) {
-        printf("-u requires -z to be specified\n");
+        error_setg(errp, "-u requires -z to be specified");
         return -EINVAL;
     }
 
     if (zflag + Pflag + sflag > 1) {
-        printf("Only one of -z, -P, and -s "
-               "can be specified at the same time\n");
+        error_setg(errp, "Only one of -z, -P, and -s "
+                   "can be specified at the same time");
         return -EINVAL;
     }
 
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[optind]);
+        set_cvtnum_err(offset, argv[optind], errp);
         return offset;
     }
 
     optind++;
     count = cvtnum(argv[optind]);
     if (count < 0) {
-        print_cvtnum_err(count, argv[optind]);
+        set_cvtnum_err(count, argv[optind], errp);
         return count;
     } else if (count > BDRV_REQUEST_MAX_BYTES &&
                !(flags & BDRV_REQ_NO_FALLBACK)) {
-        printf("length cannot exceed %" PRIu64 " without -n, given %s\n",
-               (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
+        error_setg(errp,
+                   "length cannot exceed %" PRIu64 " without -n, given %s",
+                   (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
         return -EINVAL;
     }
 
     if (bflag || cflag) {
         if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
-            printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
-                   offset);
+            error_setg(errp,
+                       "%" PRId64 " is not a sector-aligned value for 'offset'",
+                       offset);
             return -EINVAL;
         }
 
         if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
-            printf("%"PRId64" is not a sector-aligned value for 'count'\n",
-                   count);
+            error_setg(errp,
+                       "%" PRId64 " is not a sector-aligned value for 'count'",
+                       count);
             return -EINVAL;
         }
     }
 
     if (zflag) {
         if (flags & BDRV_REQ_REGISTERED_BUF) {
-            printf("cannot combine zero write with registered I/O buffer\n");
+            error_setg(errp,
+                       "cannot combine zero write with registered I/O buffer");
             return -EINVAL;
         }
     } else {
         if (sflag) {
             buf = qemu_io_alloc_from_file(blk, count, file_name,
-                                          flags & BDRV_REQ_REGISTERED_BUF);
+                                          flags & BDRV_REQ_REGISTERED_BUF,
+                                          errp);
             if (!buf) {
                 return -EINVAL;
             }
@@ -1203,7 +1214,7 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
     clock_gettime(CLOCK_MONOTONIC, &t2);
 
     if (ret < 0) {
-        printf("write failed: %s\n", strerror(-ret));
+        error_setg(errp, "write failed: %s", strerror(-ret));
         goto out;
     }
     cnt = ret;
@@ -1245,7 +1256,7 @@ writev_help(void)
 "\n");
 }
 
-static int writev_f(BlockBackend *blk, int argc, char **argv);
+static int writev_f(BlockBackend *blk, int argc, char **argv, Error **errp);
 
 static const cmdinfo_t writev_cmd = {
     .name       = "writev",
@@ -1258,7 +1269,7 @@ static const cmdinfo_t writev_cmd = {
     .help       = writev_help,
 };
 
-static int writev_f(BlockBackend *blk, int argc, char **argv)
+static int writev_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     struct timespec t1, t2;
     bool Cflag = false, qflag = false;
@@ -1287,7 +1298,7 @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
             flags |= BDRV_REQ_REGISTERED_BUF;
             break;
         case 'P':
-            pattern = parse_pattern(optarg);
+            pattern = parse_pattern(optarg, errp);
             if (pattern < 0) {
                 return -EINVAL;
             }
@@ -1305,14 +1316,14 @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
 
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[optind]);
+        set_cvtnum_err(offset, argv[optind], errp);
         return offset;
     }
     optind++;
 
     nr_iov = argc - optind;
     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern,
-                       flags & BDRV_REQ_REGISTERED_BUF);
+                       flags & BDRV_REQ_REGISTERED_BUF, errp);
     if (buf == NULL) {
         return -EINVAL;
     }
@@ -1322,7 +1333,7 @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
     clock_gettime(CLOCK_MONOTONIC, &t2);
 
     if (ret < 0) {
-        printf("writev failed: %s\n", strerror(-ret));
+        error_setg(errp, "writev failed: %s", strerror(-ret));
         goto out;
     }
     cnt = ret;
@@ -1367,7 +1378,7 @@ static void aio_write_done(void *opaque, int ret)
 
 
     if (ret < 0) {
-        printf("aio_write failed: %s\n", strerror(-ret));
+        error_report("aio_write failed: %s", strerror(-ret));
         block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
         goto out;
     }
@@ -1399,7 +1410,7 @@ static void aio_read_done(void *opaque, int ret)
     clock_gettime(CLOCK_MONOTONIC, &t2);
 
     if (ret < 0) {
-        printf("readv failed: %s\n", strerror(-ret));
+        error_report("readv failed: %s", strerror(-ret));
         block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
         goto out;
     }
@@ -1409,8 +1420,8 @@ static void aio_read_done(void *opaque, int ret)
 
         memset(cmp_buf, ctx->pattern, ctx->qiov.size);
         if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
-            printf("Pattern verification failed at offset %"
-                   PRId64 ", %zu bytes\n", ctx->offset, ctx->qiov.size);
+            error_report("Pattern verification failed at offset %"
+                         PRId64 ", %zu bytes", ctx->offset, ctx->qiov.size);
         }
         g_free(cmp_buf);
     }
@@ -1461,7 +1472,7 @@ static void aio_read_help(void)
 "\n");
 }
 
-static int aio_read_f(BlockBackend *blk, int argc, char **argv);
+static int aio_read_f(BlockBackend *blk, int argc, char **argv, Error **errp);
 
 static const cmdinfo_t aio_read_cmd = {
     .name       = "aio_read",
@@ -1473,7 +1484,7 @@ static const cmdinfo_t aio_read_cmd = {
     .help       = aio_read_help,
 };
 
-static int aio_read_f(BlockBackend *blk, int argc, char **argv)
+static int aio_read_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int nr_iov, c;
     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
@@ -1486,7 +1497,7 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
             break;
         case 'P':
             ctx->Pflag = true;
-            ctx->pattern = parse_pattern(optarg);
+            ctx->pattern = parse_pattern(optarg, errp);
             if (ctx->pattern < 0) {
                 g_free(ctx);
                 return -EINVAL;
@@ -1522,7 +1533,7 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
     ctx->offset = cvtnum(argv[optind]);
     if (ctx->offset < 0) {
         int ret = ctx->offset;
-        print_cvtnum_err(ret, argv[optind]);
+        set_cvtnum_err(ret, argv[optind], errp);
         g_free(ctx);
         return ret;
     }
@@ -1530,7 +1541,7 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
 
     nr_iov = argc - optind;
     ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, 0xab,
-                            ctx->flags & BDRV_REQ_REGISTERED_BUF);
+                            ctx->flags & BDRV_REQ_REGISTERED_BUF, errp);
     if (ctx->buf == NULL) {
         block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
         g_free(ctx);
@@ -1573,7 +1584,7 @@ static void aio_write_help(void)
 "\n");
 }
 
-static int aio_write_f(BlockBackend *blk, int argc, char **argv);
+static int aio_write_f(BlockBackend *blk, int argc, char **argv, Error **errp);
 
 static const cmdinfo_t aio_write_cmd = {
     .name       = "aio_write",
@@ -1586,7 +1597,7 @@ static const cmdinfo_t aio_write_cmd = {
     .help       = aio_write_help,
 };
 
-static int aio_write_f(BlockBackend *blk, int argc, char **argv)
+static int aio_write_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int nr_iov, c;
     int pattern = 0xcd;
@@ -1611,7 +1622,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
             ctx->flags |= BDRV_REQ_MAY_UNMAP;
             break;
         case 'P':
-            pattern = parse_pattern(optarg);
+            pattern = parse_pattern(optarg, errp);
             if (pattern < 0) {
                 g_free(ctx);
                 return -EINVAL;
@@ -1639,25 +1650,26 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
     }
 
     if (ctx->zflag && optind != argc - 2) {
-        printf("-z supports only a single length parameter\n");
+        error_setg(errp, "-z supports only a single length parameter");
         g_free(ctx);
         return -EINVAL;
     }
 
     if ((ctx->flags & BDRV_REQ_MAY_UNMAP) && !ctx->zflag) {
-        printf("-u requires -z to be specified\n");
+        error_setg(errp, "-u requires -z to be specified");
         g_free(ctx);
         return -EINVAL;
     }
 
     if (ctx->zflag && ctx->Pflag) {
-        printf("-z and -P cannot be specified at the same time\n");
+        error_setg(errp, "-z and -P cannot be specified at the same time");
         g_free(ctx);
         return -EINVAL;
     }
 
     if (ctx->zflag && (ctx->flags & BDRV_REQ_REGISTERED_BUF)) {
-        printf("cannot combine zero write with registered I/O buffer\n");
+        error_setg(errp,
+                   "cannot combine zero write with registered I/O buffer");
         g_free(ctx);
         return -EINVAL;
     }
@@ -1665,7 +1677,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
     ctx->offset = cvtnum(argv[optind]);
     if (ctx->offset < 0) {
         int ret = ctx->offset;
-        print_cvtnum_err(ret, argv[optind]);
+        set_cvtnum_err(ret, argv[optind], errp);
         g_free(ctx);
         return ret;
     }
@@ -1674,7 +1686,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
     if (ctx->zflag) {
         int64_t count = cvtnum(argv[optind]);
         if (count < 0) {
-            print_cvtnum_err(count, argv[optind]);
+            set_cvtnum_err(count, argv[optind], errp);
             g_free(ctx);
             return count;
         }
@@ -1685,7 +1697,8 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
     } else {
         nr_iov = argc - optind;
         ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov,
-                                pattern, ctx->flags & BDRV_REQ_REGISTERED_BUF);
+                                pattern,
+                                ctx->flags & BDRV_REQ_REGISTERED_BUF, errp);
         if (ctx->buf == NULL) {
             block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
             g_free(ctx);
@@ -1703,7 +1716,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
     return 0;
 }
 
-static int aio_flush_f(BlockBackend *blk, int argc, char **argv)
+static int aio_flush_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     BlockAcctCookie cookie;
     block_acct_start(blk_get_stats(blk), &cookie, 0, BLOCK_ACCT_FLUSH);
@@ -1718,7 +1731,7 @@ static const cmdinfo_t aio_flush_cmd = {
     .oneline    = "completes all outstanding aio requests"
 };
 
-static int flush_f(BlockBackend *blk, int argc, char **argv)
+static int flush_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     return blk_flush(blk);
 }
@@ -1735,7 +1748,7 @@ static inline int64_t tosector(int64_t bytes)
     return bytes >> BDRV_SECTOR_BITS;
 }
 
-static int zone_report_f(BlockBackend *blk, int argc, char **argv)
+static int zone_report_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int ret;
     int64_t offset;
@@ -1745,17 +1758,17 @@ static int zone_report_f(BlockBackend *blk, int argc, char **argv)
     ++optind;
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[optind]);
+        set_cvtnum_err(offset, argv[optind], errp);
         return offset;
     }
     ++optind;
     val = cvtnum(argv[optind]);
     if (val < 0) {
-        print_cvtnum_err(val, argv[optind]);
+        set_cvtnum_err(val, argv[optind], errp);
         return val;
     }
     if (val > UINT_MAX) {
-        printf("Number of zones must be less than 2^32\n");
+        error_setg(errp, "Number of zones must be less than 2^32");
         return -ERANGE;
     }
     nr_zones = val;
@@ -1764,7 +1777,7 @@ static int zone_report_f(BlockBackend *blk, int argc, char **argv)
     zones = g_new(BlockZoneDescriptor, nr_zones);
     ret = blk_zone_report(blk, offset, &nr_zones, zones);
     if (ret < 0) {
-        printf("zone report failed: %s\n", strerror(-ret));
+        error_setg(errp, "zone report failed: %s", strerror(-ret));
     } else {
         for (int i = 0; i < nr_zones; ++i) {
             printf("start: 0x%" PRIx64 ", len 0x%" PRIx64 ", "
@@ -1788,25 +1801,25 @@ static const cmdinfo_t zone_report_cmd = {
     .oneline = "report zone information",
 };
 
-static int zone_open_f(BlockBackend *blk, int argc, char **argv)
+static int zone_open_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int ret;
     int64_t offset, len;
     ++optind;
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[optind]);
+        set_cvtnum_err(offset, argv[optind], errp);
         return offset;
     }
     ++optind;
     len = cvtnum(argv[optind]);
     if (len < 0) {
-        print_cvtnum_err(len, argv[optind]);
+        set_cvtnum_err(len, argv[optind], errp);
         return len;
     }
     ret = blk_zone_mgmt(blk, BLK_ZO_OPEN, offset, len);
     if (ret < 0) {
-        printf("zone open failed: %s\n", strerror(-ret));
+        error_setg(errp, "zone open failed: %s", strerror(-ret));
     }
     return ret;
 }
@@ -1821,25 +1834,25 @@ static const cmdinfo_t zone_open_cmd = {
     .oneline = "explicit open a range of zones in zone block device",
 };
 
-static int zone_close_f(BlockBackend *blk, int argc, char **argv)
+static int zone_close_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int ret;
     int64_t offset, len;
     ++optind;
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[optind]);
+        set_cvtnum_err(offset, argv[optind], errp);
         return offset;
     }
     ++optind;
     len = cvtnum(argv[optind]);
     if (len < 0) {
-        print_cvtnum_err(len, argv[optind]);
+        set_cvtnum_err(len, argv[optind], errp);
         return len;
     }
     ret = blk_zone_mgmt(blk, BLK_ZO_CLOSE, offset, len);
     if (ret < 0) {
-        printf("zone close failed: %s\n", strerror(-ret));
+        error_setg(errp, "zone close failed: %s", strerror(-ret));
     }
     return ret;
 }
@@ -1854,25 +1867,25 @@ static const cmdinfo_t zone_close_cmd = {
     .oneline = "close a range of zones in zone block device",
 };
 
-static int zone_finish_f(BlockBackend *blk, int argc, char **argv)
+static int zone_finish_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int ret;
     int64_t offset, len;
     ++optind;
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[optind]);
+        set_cvtnum_err(offset, argv[optind], errp);
         return offset;
     }
     ++optind;
     len = cvtnum(argv[optind]);
     if (len < 0) {
-        print_cvtnum_err(len, argv[optind]);
+        set_cvtnum_err(len, argv[optind], errp);
         return len;
     }
     ret = blk_zone_mgmt(blk, BLK_ZO_FINISH, offset, len);
     if (ret < 0) {
-        printf("zone finish failed: %s\n", strerror(-ret));
+        error_setg(errp, "zone finish failed: %s", strerror(-ret));
     }
     return ret;
 }
@@ -1887,25 +1900,25 @@ static const cmdinfo_t zone_finish_cmd = {
     .oneline = "finish a range of zones in zone block device",
 };
 
-static int zone_reset_f(BlockBackend *blk, int argc, char **argv)
+static int zone_reset_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int ret;
     int64_t offset, len;
     ++optind;
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[optind]);
+        set_cvtnum_err(offset, argv[optind], errp);
         return offset;
     }
     ++optind;
     len = cvtnum(argv[optind]);
     if (len < 0) {
-        print_cvtnum_err(len, argv[optind]);
+        set_cvtnum_err(len, argv[optind], errp);
         return len;
     }
     ret = blk_zone_mgmt(blk, BLK_ZO_RESET, offset, len);
     if (ret < 0) {
-        printf("zone reset failed: %s\n", strerror(-ret));
+        error_setg(errp, "zone reset failed: %s", strerror(-ret));
     }
     return ret;
 }
@@ -1934,7 +1947,7 @@ static int do_aio_zone_append(BlockBackend *blk, QEMUIOVector *qiov,
     return async_ret < 0 ? async_ret : 1;
 }
 
-static int zone_append_f(BlockBackend *blk, int argc, char **argv)
+static int zone_append_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int ret;
     bool pflag = false;
@@ -1956,19 +1969,19 @@ static int zone_append_f(BlockBackend *blk, int argc, char **argv)
 
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[optind]);
+        set_cvtnum_err(offset, argv[optind], errp);
         return offset;
     }
     optind++;
     nr_iov = argc - optind;
     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern,
-                       flags & BDRV_REQ_REGISTERED_BUF);
+                       flags & BDRV_REQ_REGISTERED_BUF, errp);
     if (buf == NULL) {
         return -EINVAL;
     }
     ret = do_aio_zone_append(blk, &qiov, &offset, flags, &total);
     if (ret < 0) {
-        printf("zone append failed: %s\n", strerror(-ret));
+        error_setg(errp, "zone append failed: %s", strerror(-ret));
         goto out;
     }
 
@@ -1994,7 +2007,7 @@ static const cmdinfo_t zone_append_cmd = {
     .oneline = "append write a number of bytes at a specified offset",
 };
 
-static int truncate_f(BlockBackend *blk, int argc, char **argv);
+static int truncate_f(BlockBackend *blk, int argc, char **argv, Error **errp);
 static const cmdinfo_t truncate_cmd = {
     .name       = "truncate",
     .altname    = "t",
@@ -2006,9 +2019,8 @@ static const cmdinfo_t truncate_cmd = {
     .oneline    = "truncates the current file at the given offset",
 };
 
-static int truncate_f(BlockBackend *blk, int argc, char **argv)
+static int truncate_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
-    Error *local_err = NULL;
     int64_t offset;
     int c, ret;
     PreallocMode prealloc = PREALLOC_MODE_OFF;
@@ -2019,7 +2031,7 @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
             prealloc = qapi_enum_parse(&PreallocMode_lookup, optarg,
                                        PREALLOC_MODE__MAX, NULL);
             if (prealloc == PREALLOC_MODE__MAX) {
-                error_report("Invalid preallocation mode '%s'", optarg);
+                error_setg(errp, "Invalid preallocation mode '%s'", optarg);
                 return -EINVAL;
             }
             break;
@@ -2031,7 +2043,7 @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
 
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[1]);
+        set_cvtnum_err(offset, argv[1], errp);
         return offset;
     }
 
@@ -2040,23 +2052,22 @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
      * exact=true.  It is better to err on the "emit more errors" side
      * than to be overly permissive.
      */
-    ret = blk_truncate(blk, offset, false, prealloc, 0, &local_err);
+    ret = blk_truncate(blk, offset, false, prealloc, 0, errp);
     if (ret < 0) {
-        error_report_err(local_err);
         return ret;
     }
 
     return 0;
 }
 
-static int length_f(BlockBackend *blk, int argc, char **argv)
+static int length_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int64_t size;
     char s1[64];
 
     size = blk_getlength(blk);
     if (size < 0) {
-        printf("getlength: %s\n", strerror(-size));
+        error_setg(errp, "getlength: %s", strerror(-size));
         return size;
     }
 
@@ -2074,12 +2085,12 @@ static const cmdinfo_t length_cmd = {
 };
 
 
-static int info_f(BlockBackend *blk, int argc, char **argv)
+static int info_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
+    ERRP_GUARD();
     BlockDriverState *bs = blk_bs(blk);
     BlockDriverInfo bdi;
     ImageInfoSpecific *spec_info;
-    Error *local_err = NULL;
     char s1[64], s2[64];
     int ret;
 
@@ -2104,9 +2115,8 @@ static int info_f(BlockBackend *blk, int argc, char **argv)
     printf("cluster size: %s\n", s1);
     printf("vm state offset: %s\n", s2);
 
-    spec_info = bdrv_get_specific_info(bs, &local_err);
-    if (local_err) {
-        error_report_err(local_err);
+    spec_info = bdrv_get_specific_info(bs, errp);
+    if (*errp) {
         return -EIO;
     }
     if (spec_info) {
@@ -2143,7 +2153,7 @@ static void discard_help(void)
 "\n");
 }
 
-static int discard_f(BlockBackend *blk, int argc, char **argv);
+static int discard_f(BlockBackend *blk, int argc, char **argv, Error **errp);
 
 static const cmdinfo_t discard_cmd = {
     .name       = "discard",
@@ -2157,7 +2167,7 @@ static const cmdinfo_t discard_cmd = {
     .help       = discard_help,
 };
 
-static int discard_f(BlockBackend *blk, int argc, char **argv)
+static int discard_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     struct timespec t1, t2;
     bool Cflag = false, qflag = false;
@@ -2185,18 +2195,18 @@ static int discard_f(BlockBackend *blk, int argc, char **argv)
 
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[optind]);
+        set_cvtnum_err(offset, argv[optind], errp);
         return offset;
     }
 
     optind++;
     bytes = cvtnum(argv[optind]);
     if (bytes < 0) {
-        print_cvtnum_err(bytes, argv[optind]);
+        set_cvtnum_err(bytes, argv[optind], errp);
         return bytes;
     } else if (bytes > BDRV_REQUEST_MAX_BYTES) {
-        printf("length cannot exceed %"PRIu64", given %s\n",
-               (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
+        error_setg(errp, "length cannot exceed %" PRIu64 ", given %s",
+                   (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
         return -EINVAL;
     }
 
@@ -2205,7 +2215,7 @@ static int discard_f(BlockBackend *blk, int argc, char **argv)
     clock_gettime(CLOCK_MONOTONIC, &t2);
 
     if (ret < 0) {
-        printf("discard failed: %s\n", strerror(-ret));
+        error_setg(errp, "discard failed: %s", strerror(-ret));
         return ret;
     }
 
@@ -2238,7 +2248,8 @@ static void aio_discard_help(void)
 "\n");
 }
 
-static int aio_discard_f(BlockBackend *blk, int argc, char **argv);
+static int aio_discard_f(BlockBackend *blk, int argc, char **argv,
+                         Error **errp);
 
 static const cmdinfo_t aio_discard_cmd = {
     .name       = "aio_discard",
@@ -2259,7 +2270,7 @@ static void aio_discard_done(void *opaque, int ret)
     clock_gettime(CLOCK_MONOTONIC, &t2);
 
     if (ret < 0) {
-        printf("aio_discard failed: %s\n", strerror(-ret));
+        error_report("aio_discard failed: %s", strerror(-ret));
         block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
         goto out;
     }
@@ -2278,7 +2289,7 @@ out:
     g_free(ctx);
 }
 
-static int aio_discard_f(BlockBackend *blk, int argc, char **argv)
+static int aio_discard_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int c, ret;
     int64_t count;
@@ -2310,7 +2321,7 @@ static int aio_discard_f(BlockBackend *blk, int argc, char **argv)
     ctx->offset = cvtnum(argv[optind]);
     if (ctx->offset < 0) {
         ret = ctx->offset;
-        print_cvtnum_err(ret, argv[optind]);
+        set_cvtnum_err(ret, argv[optind], errp);
         g_free(ctx);
         return ret;
     }
@@ -2318,7 +2329,7 @@ static int aio_discard_f(BlockBackend *blk, int argc, char **argv)
 
     count = cvtnum(argv[optind]);
     if (count < 0) {
-        print_cvtnum_err(count, argv[optind]);
+        set_cvtnum_err(count, argv[optind], errp);
         g_free(ctx);
         return count;
     }
@@ -2332,7 +2343,7 @@ static int aio_discard_f(BlockBackend *blk, int argc, char **argv)
     return 0;
 }
 
-static int alloc_f(BlockBackend *blk, int argc, char **argv)
+static int alloc_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     BlockDriverState *bs = blk_bs(blk);
     int64_t offset, start, remaining, count;
@@ -2342,14 +2353,14 @@ static int alloc_f(BlockBackend *blk, int argc, char **argv)
 
     start = offset = cvtnum(argv[1]);
     if (offset < 0) {
-        print_cvtnum_err(offset, argv[1]);
+        set_cvtnum_err(offset, argv[1], errp);
         return offset;
     }
 
     if (argc == 3) {
         count = cvtnum(argv[2]);
         if (count < 0) {
-            print_cvtnum_err(count, argv[2]);
+            set_cvtnum_err(count, argv[2], errp);
             return count;
         }
     } else {
@@ -2361,7 +2372,7 @@ static int alloc_f(BlockBackend *blk, int argc, char **argv)
     while (remaining) {
         ret = bdrv_is_allocated(bs, offset, remaining, &num);
         if (ret < 0) {
-            printf("is_allocated failed: %s\n", strerror(-ret));
+            error_setg(errp, "is_allocated failed: %s", strerror(-ret));
             return ret;
         }
         offset += num;
@@ -2422,7 +2433,7 @@ static int map_is_allocated(BlockDriverState *bs, int64_t offset,
     return firstret;
 }
 
-static int map_f(BlockBackend *blk, int argc, char **argv)
+static int map_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int64_t offset, bytes;
     char s1[64], s2[64];
@@ -2433,17 +2444,18 @@ static int map_f(BlockBackend *blk, int argc, char **argv)
     offset = 0;
     bytes = blk_getlength(blk);
     if (bytes < 0) {
-        error_report("Failed to query image length: %s", strerror(-bytes));
+        error_setg(errp, "Failed to query image length: %s", strerror(-bytes));
         return bytes;
     }
 
     while (bytes) {
         ret = map_is_allocated(blk_bs(blk), offset, bytes, &num);
         if (ret < 0) {
-            error_report("Failed to get allocation status: %s", strerror(-ret));
+            error_setg(errp, "Failed to get allocation status: %s",
+                       strerror(-ret));
             return ret;
         } else if (!num) {
-            error_report("Unexpected end of image");
+            error_setg(errp, "Unexpected end of image");
             return -EIO;
         }
 
@@ -2485,7 +2497,7 @@ static void reopen_help(void)
 "\n");
 }
 
-static int reopen_f(BlockBackend *blk, int argc, char **argv);
+static int reopen_f(BlockBackend *blk, int argc, char **argv, Error **errp);
 
 static QemuOptsList reopen_opts = {
     .name = "reopen",
@@ -2507,7 +2519,7 @@ static const cmdinfo_t reopen_cmd = {
        .help           = reopen_help,
 };
 
-static int reopen_f(BlockBackend *blk, int argc, char **argv)
+static int reopen_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     BlockDriverState *bs = blk_bs(blk);
     QemuOpts *qopts;
@@ -2517,13 +2529,12 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
     bool writethrough = !blk_enable_write_cache(blk);
     bool has_rw_option = false;
     bool has_cache_option = false;
-    Error *local_err = NULL;
 
     while ((c = getopt(argc, argv, "c:o:rw")) != -1) {
         switch (c) {
         case 'c':
             if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) {
-                error_report("Invalid cache option: %s", optarg);
+                error_setg(errp, "Invalid cache option: %s", optarg);
                 return -EINVAL;
             }
             has_cache_option = true;
@@ -2536,7 +2547,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
             break;
         case 'r':
             if (has_rw_option) {
-                error_report("Only one -r/-w option may be given");
+                error_setg(errp, "Only one -r/-w option may be given");
                 return -EINVAL;
             }
             flags &= ~BDRV_O_RDWR;
@@ -2544,7 +2555,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
             break;
         case 'w':
             if (has_rw_option) {
-                error_report("Only one -r/-w option may be given");
+                error_setg(errp, "Only one -r/-w option may be given");
                 return -EINVAL;
             }
             flags |= BDRV_O_RDWR;
@@ -2566,7 +2577,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
     if (!writethrough != blk_enable_write_cache(blk) &&
         blk_get_attached_dev(blk))
     {
-        error_report("Cannot change cache.writeback: Device attached");
+        error_setg(errp, "Cannot change cache.writeback: Device attached");
         qemu_opts_reset(&reopen_opts);
         return -EBUSY;
     }
@@ -2589,7 +2600,8 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
 
     if (qdict_haskey(opts, BDRV_OPT_READ_ONLY)) {
         if (has_rw_option) {
-            error_report("Cannot set both -r/-w and '" BDRV_OPT_READ_ONLY "'");
+            error_setg(errp,
+                       "Cannot set both -r/-w and '" BDRV_OPT_READ_ONLY "'");
             qobject_unref(opts);
             return -EINVAL;
         }
@@ -2600,7 +2612,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
     if (qdict_haskey(opts, BDRV_OPT_CACHE_DIRECT) ||
         qdict_haskey(opts, BDRV_OPT_CACHE_NO_FLUSH)) {
         if (has_cache_option) {
-            error_report("Cannot set both -c and the cache options");
+            error_setg(errp, "Cannot set both -c and the cache options");
             qobject_unref(opts);
             return -EINVAL;
         }
@@ -2609,10 +2621,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
         qdict_put_bool(opts, BDRV_OPT_CACHE_NO_FLUSH, flags & BDRV_O_NO_FLUSH);
     }
 
-    bdrv_reopen(bs, opts, true, &local_err);
-
-    if (local_err) {
-        error_report_err(local_err);
+    if (bdrv_reopen(bs, opts, true, errp) < 0) {
         return -EINVAL;
     }
 
@@ -2620,26 +2629,28 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
     return 0;
 }
 
-static int break_f(BlockBackend *blk, int argc, char **argv)
+static int break_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int ret;
 
     ret = bdrv_debug_breakpoint(blk_bs(blk), argv[1], argv[2]);
     if (ret < 0) {
-        printf("Could not set breakpoint: %s\n", strerror(-ret));
+        error_setg(errp, "Could not set breakpoint: %s", strerror(-ret));
         return ret;
     }
 
     return 0;
 }
 
-static int remove_break_f(BlockBackend *blk, int argc, char **argv)
+static int remove_break_f(BlockBackend *blk, int argc, char **argv,
+                           Error **errp)
 {
     int ret;
 
     ret = bdrv_debug_remove_breakpoint(blk_bs(blk), argv[1]);
     if (ret < 0) {
-        printf("Could not remove breakpoint %s: %s\n", argv[1], strerror(-ret));
+        error_setg(errp, "Could not remove breakpoint %s: %s",
+                   argv[1], strerror(-ret));
         return ret;
     }
 
@@ -2665,13 +2676,13 @@ static const cmdinfo_t remove_break_cmd = {
        .oneline        = "remove a breakpoint by tag",
 };
 
-static int resume_f(BlockBackend *blk, int argc, char **argv)
+static int resume_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int ret;
 
     ret = bdrv_debug_resume(blk_bs(blk), argv[1]);
     if (ret < 0) {
-        printf("Could not resume request: %s\n", strerror(-ret));
+        error_setg(errp, "Could not resume request: %s", strerror(-ret));
         return ret;
     }
 
@@ -2687,7 +2698,7 @@ static const cmdinfo_t resume_cmd = {
        .oneline        = "resumes the request tagged as tag",
 };
 
-static int wait_break_f(BlockBackend *blk, int argc, char **argv)
+static int wait_break_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     while (!bdrv_debug_is_suspended(blk_bs(blk), argv[1])) {
         aio_poll(blk_get_aio_context(blk), true);
@@ -2704,7 +2715,7 @@ static const cmdinfo_t wait_break_cmd = {
        .oneline        = "waits for the suspension of a request",
 };
 
-static int abort_f(BlockBackend *blk, int argc, char **argv)
+static int abort_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     abort();
 }
@@ -2730,7 +2741,7 @@ static void sigraise_help(void)
 "\n", SIGTERM);
 }
 
-static int sigraise_f(BlockBackend *blk, int argc, char **argv);
+static int sigraise_f(BlockBackend *blk, int argc, char **argv, Error **errp);
 
 static const cmdinfo_t sigraise_cmd = {
     .name       = "sigraise",
@@ -2743,15 +2754,16 @@ static const cmdinfo_t sigraise_cmd = {
     .help       = sigraise_help,
 };
 
-static int sigraise_f(BlockBackend *blk, int argc, char **argv)
+static int sigraise_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int64_t sig = cvtnum(argv[1]);
     if (sig < 0) {
-        print_cvtnum_err(sig, argv[1]);
+        set_cvtnum_err(sig, argv[1], errp);
         return sig;
     } else if (sig > NSIG) {
-        printf("signal argument '%s' is too large to be a valid signal\n",
-               argv[1]);
+        error_setg(errp,
+                   "signal argument '%s' is too large to be a valid signal",
+                   argv[1]);
         return -EINVAL;
     }
 
@@ -2772,7 +2784,7 @@ static void sleep_cb(void *opaque)
     *expired = true;
 }
 
-static int sleep_f(BlockBackend *blk, int argc, char **argv)
+static int sleep_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     char *endptr;
     long ms;
@@ -2781,7 +2793,7 @@ static int sleep_f(BlockBackend *blk, int argc, char **argv)
 
     ms = strtol(argv[1], &endptr, 0);
     if (ms < 0 || *endptr != '\0') {
-        printf("%s is not a valid number\n", argv[1]);
+        error_setg(errp, "%s is not a valid number", argv[1]);
         return -EINVAL;
     }
 
@@ -2833,7 +2845,7 @@ static void help_all(void)
     printf("\nUse 'help commandname' for extended help.\n");
 }
 
-static int help_f(BlockBackend *blk, int argc, char **argv)
+static int help_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     const cmdinfo_t *ct;
 
@@ -2844,7 +2856,7 @@ static int help_f(BlockBackend *blk, int argc, char **argv)
 
     ct = find_command(argv[1]);
     if (ct == NULL) {
-        printf("command %s not found\n", argv[1]);
+        error_setg(errp, "command %s not found", argv[1]);
         return -EINVAL;
     }
 
@@ -2867,7 +2879,7 @@ static const cmdinfo_t help_cmd = {
  * Called with aio context of blk acquired. Or with qemu_get_aio_context()
  * context acquired if blk is NULL.
  */
-int qemuio_command(BlockBackend *blk, const char *cmd)
+int qemuio_command(BlockBackend *blk, const char *cmd, Error **errp)
 {
     char *input;
     const cmdinfo_t *ct;
@@ -2880,9 +2892,9 @@ int qemuio_command(BlockBackend *blk, const char *cmd)
     if (c) {
         ct = find_command(v[0]);
         if (ct) {
-            ret = command(blk, ct, c, v);
+            ret = command(blk, ct, c, v, errp);
         } else {
-            fprintf(stderr, "command \"%s\" not found\n", v[0]);
+            error_setg(errp, "command \"%s\" not found", v[0]);
             ret = -EINVAL;
         }
     }
diff --git a/qemu-io.c b/qemu-io.c
index 8f2de83f3c80..598d5b1c9ca9 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -68,7 +68,7 @@ static int get_eof_char(void)
 #endif
 }
 
-static int close_f(BlockBackend *blk, int argc, char **argv)
+static int close_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     blk_unref(qemuio_blk);
     qemuio_blk = NULL;
@@ -140,7 +140,7 @@ static void open_help(void)
 "\n");
 }
 
-static int open_f(BlockBackend *blk, int argc, char **argv);
+static int open_f(BlockBackend *blk, int argc, char **argv, Error **errp);
 
 static const cmdinfo_t open_cmd = {
     .name       = "open",
@@ -164,7 +164,7 @@ static QemuOptsList empty_opts = {
     },
 };
 
-static int open_f(BlockBackend *blk, int argc, char **argv)
+static int open_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     int flags = BDRV_O_UNMAP;
     int readonly = 0;
@@ -268,7 +268,7 @@ static int open_f(BlockBackend *blk, int argc, char **argv)
     return 0;
 }
 
-static int quit_f(BlockBackend *blk, int argc, char **argv)
+static int quit_f(BlockBackend *blk, int argc, char **argv, Error **errp)
 {
     quit_qemu_io = true;
     return 0;
@@ -414,7 +414,14 @@ static void prep_fetchline(void *opaque)
 
 static int do_qemuio_command(const char *cmd)
 {
-    return qemuio_command(qemuio_blk, cmd);
+    Error *local_err = NULL;
+    int ret;
+
+    ret = qemuio_command(qemuio_blk, cmd, &local_err);
+    if (local_err) {
+        error_report_err(local_err);
+    }
+    return ret;
 }
 
 static int command_loop(void)
diff --git a/tests/qemu-iotests/004.out b/tests/qemu-iotests/004.out
index fb8593289f51..37da6024809f 100644
--- a/tests/qemu-iotests/004.out
+++ b/tests/qemu-iotests/004.out
@@ -6,36 +6,36 @@ wrote 1048576/1048576 bytes at offset 133169152
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 write into image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 write at image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 write past image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 pwrite past image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 writev past image boundary
-writev failed: Input/output error
+qemu-io: writev failed: Input/output error
 
 read before image boundary
 read 1048576/1048576 bytes at offset 133169152
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 read into image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 read at image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 read past image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 pread past image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 readv past image boundary
-readv failed: Input/output error
+qemu-io: readv failed: Input/output error
 *** done
diff --git a/tests/qemu-iotests/021.out b/tests/qemu-iotests/021.out
index 8533f8e58ae6..dfdfeb503780 100644
--- a/tests/qemu-iotests/021.out
+++ b/tests/qemu-iotests/021.out
@@ -2,92 +2,92 @@ QA output created by 021
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
 
 == testing writev -P -1 ==
--1 is not a valid pattern byte
+qemu-io: -1 is not a valid pattern byte
 
 == testing read -P -1 ==
--1 is not a valid pattern byte
+qemu-io: -1 is not a valid pattern byte
 
 == testing write -P -1 ==
--1 is not a valid pattern byte
+qemu-io: -1 is not a valid pattern byte
 
 == testing readv -P -1 ==
--1 is not a valid pattern byte
+qemu-io: -1 is not a valid pattern byte
 
 == testing aio_read -P -1 ==
--1 is not a valid pattern byte
+qemu-io: -1 is not a valid pattern byte
 
 == testing aio_write -P -1 ==
--1 is not a valid pattern byte
+qemu-io: -1 is not a valid pattern byte
 
 == testing writev -P 300 ==
-300 is not a valid pattern byte
+qemu-io: 300 is not a valid pattern byte
 
 == testing read -P 300 ==
-300 is not a valid pattern byte
+qemu-io: 300 is not a valid pattern byte
 
 == testing write -P 300 ==
-300 is not a valid pattern byte
+qemu-io: 300 is not a valid pattern byte
 
 == testing readv -P 300 ==
-300 is not a valid pattern byte
+qemu-io: 300 is not a valid pattern byte
 
 == testing aio_read -P 300 ==
-300 is not a valid pattern byte
+qemu-io: 300 is not a valid pattern byte
 
 == testing aio_write -P 300 ==
-300 is not a valid pattern byte
+qemu-io: 300 is not a valid pattern byte
 
 == testing writev -P 12m ==
-12m is not a valid pattern byte
+qemu-io: 12m is not a valid pattern byte
 
 == testing read -P 12m ==
-12m is not a valid pattern byte
+qemu-io: 12m is not a valid pattern byte
 
 == testing write -P 12m ==
-12m is not a valid pattern byte
+qemu-io: 12m is not a valid pattern byte
 
 == testing readv -P 12m ==
-12m is not a valid pattern byte
+qemu-io: 12m is not a valid pattern byte
 
 == testing aio_read -P 12m ==
-12m is not a valid pattern byte
+qemu-io: 12m is not a valid pattern byte
 
 == testing aio_write -P 12m ==
-12m is not a valid pattern byte
+qemu-io: 12m is not a valid pattern byte
 
 == testing writev -P 4k ==
-4k is not a valid pattern byte
+qemu-io: 4k is not a valid pattern byte
 
 == testing read -P 4k ==
-4k is not a valid pattern byte
+qemu-io: 4k is not a valid pattern byte
 
 == testing write -P 4k ==
-4k is not a valid pattern byte
+qemu-io: 4k is not a valid pattern byte
 
 == testing readv -P 4k ==
-4k is not a valid pattern byte
+qemu-io: 4k is not a valid pattern byte
 
 == testing aio_read -P 4k ==
-4k is not a valid pattern byte
+qemu-io: 4k is not a valid pattern byte
 
 == testing aio_write -P 4k ==
-4k is not a valid pattern byte
+qemu-io: 4k is not a valid pattern byte
 
 == testing writev -P route66 ==
-route66 is not a valid pattern byte
+qemu-io: route66 is not a valid pattern byte
 
 == testing read -P route66 ==
-route66 is not a valid pattern byte
+qemu-io: route66 is not a valid pattern byte
 
 == testing write -P route66 ==
-route66 is not a valid pattern byte
+qemu-io: route66 is not a valid pattern byte
 
 == testing readv -P route66 ==
-route66 is not a valid pattern byte
+qemu-io: route66 is not a valid pattern byte
 
 == testing aio_read -P route66 ==
-route66 is not a valid pattern byte
+qemu-io: route66 is not a valid pattern byte
 
 == testing aio_write -P route66 ==
-route66 is not a valid pattern byte
+qemu-io: route66 is not a valid pattern byte
 *** done
diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out
index 83989996ff62..b998a9ac83da 100644
--- a/tests/qemu-iotests/026.out
+++ b/tests/qemu-iotests/026.out
@@ -4,442 +4,442 @@ Errors while writing 128 kB
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_update; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_update; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_update; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_update; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_update; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_update; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_update; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_update; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_load; errno: 5; imm: off; once: on; write
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
-read failed: Input/output error
+qemu-io: write failed: Input/output error
+qemu-io: read failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_load; errno: 5; imm: off; once: on; write -b
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
-read failed: Input/output error
+qemu-io: write failed: Input/output error
+qemu-io: read failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_load; errno: 5; imm: off; once: off; write
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
-read failed: Input/output error
+qemu-io: write failed: Input/output error
+qemu-io: read failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_load; errno: 5; imm: off; once: off; write -b
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
-read failed: Input/output error
+qemu-io: write failed: Input/output error
+qemu-io: read failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_load; errno: 28; imm: off; once: on; write
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: No space left on device
-read failed: No space left on device
+qemu-io: write failed: No space left on device
+qemu-io: read failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_load; errno: 28; imm: off; once: on; write -b
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: No space left on device
-read failed: No space left on device
+qemu-io: write failed: No space left on device
+qemu-io: read failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_load; errno: 28; imm: off; once: off; write
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: No space left on device
-read failed: No space left on device
+qemu-io: write failed: No space left on device
+qemu-io: read failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_load; errno: 28; imm: off; once: off; write -b
 wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: No space left on device
-read failed: No space left on device
+qemu-io: write failed: No space left on device
+qemu-io: read failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_update; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_update; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_update; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_update; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_update; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_update; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_update; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_update; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_alloc_write; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_alloc_write; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_alloc_write; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_alloc_write; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_alloc_write; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_alloc_write; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_alloc_write; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l2_alloc_write; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: write_aio; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: write_aio; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: write_aio; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: write_aio; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: write_aio; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: write_aio; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: write_aio; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: write_aio; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_load; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_load; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_load; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_load; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_load; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_load; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_load; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_load; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_update_part; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_update_part; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_update_part; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_update_part; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_update_part; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_update_part; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_update_part; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_update_part; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: cluster_alloc; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: cluster_alloc; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: cluster_alloc; errno: 5; imm: off; once: off; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: cluster_alloc; errno: 5; imm: off; once: off; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: cluster_alloc; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: cluster_alloc; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: cluster_alloc; errno: 28; imm: off; once: off; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: cluster_alloc; errno: 28; imm: off; once: off; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 
 === Refcount table growth tests ===
@@ -447,122 +447,122 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_hookup; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_hookup; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write_table; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write_table; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_switch_table; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_switch_table; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 
 === L1 growth tests ===
@@ -570,76 +570,76 @@ No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_alloc_table; errno: 5; imm: off; once: on
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_alloc_table; errno: 5; imm: off; once: off
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_alloc_table; errno: 28; imm: off; once: on
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_alloc_table; errno: 28; imm: off; once: off
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_write_table; errno: 5; imm: off; once: on
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_write_table; errno: 5; imm: off; once: off
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_write_table; errno: 28; imm: off; once: on
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_write_table; errno: 28; imm: off; once: off
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_activate_table; errno: 5; imm: off; once: on
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_activate_table; errno: 5; imm: off; once: off
+qemu-io: write failed: Input/output error
 qemu-io: Failed to flush the L2 table cache: Input/output error
 qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_activate_table; errno: 28; imm: off; once: on
-write failed: No space left on device
+qemu-io: write failed: No space left on device
 No errors were found on the image.
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
 
 Event: l1_grow_activate_table; errno: 28; imm: off; once: off
+qemu-io: write failed: No space left on device
 qemu-io: Failed to flush the L2 table cache: No space left on device
 qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
 No errors were found on the image.
 
 === Avoid cluster leaks after temporary failure ===
 
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 wrote 1048576/1048576 bytes at offset 0
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 No errors were found on the image.
@@ -651,6 +651,6 @@ wrote 1024/1024 bytes at offset 0
 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 1024/1024 bytes at offset 0
 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 *** done
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
index a37bf446e942..27275fd6b70e 100644
--- a/tests/qemu-iotests/060.out
+++ b/tests/qemu-iotests/060.out
@@ -9,7 +9,7 @@ ERROR cluster 3 refcount=1 reference=3
 Data may be corrupted, or further writes to the image may corrupt it.
 incompatible_features     []
 qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with active L1 table); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 incompatible_features     [1]
 image: TEST_DIR/t.IMGFMT
 file format: IMGFMT
@@ -23,7 +23,7 @@ Format specific information:
     corrupt: true
     extended l2: false
 qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 read 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
@@ -37,7 +37,7 @@ ERROR cluster 2 refcount=1 reference=2
 Data may be corrupted, or further writes to the image may corrupt it.
 incompatible_features     []
 qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with refcount block); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 incompatible_features     [1]
 ERROR refcount block 0 refcount=2
 ERROR cluster 2 refcount=1 reference=2
@@ -73,7 +73,7 @@ Data may be corrupted, or further writes to the image may corrupt it.
 This means waste of disk space, but no harm to data.
 incompatible_features     []
 qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with inactive L2 table); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 incompatible_features     [1]
 ERROR cluster 4 refcount=1 reference=2
 Leaked cluster 9 refcount=1 reference=0
@@ -108,10 +108,10 @@ wrote 65536/65536 bytes at offset 0
 wrote 65536/65536 bytes at offset 536870912
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with active L2 table); further corruption events will be suppressed
+qemu-io: write failed: Input/output error
+qemu-io: aio_write failed: No medium found
 blkdebug: Suspended request '0'
-write failed: Input/output error
 blkdebug: Resuming request '0'
-aio_write failed: No medium found
 
 === Testing unallocated image header ===
 
@@ -119,7 +119,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with qcow2_header); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 === Testing unaligned L1 entry ===
 
@@ -127,7 +127,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qcow2: Marking image as corrupt: L2 table offset 0x42a00 unaligned (L1 index: 0); further corruption events will be suppressed
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -140,7 +140,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qcow2: Marking image as corrupt: Cluster allocation offset 0x52a00 unaligned (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Testing unaligned pre-allocated zero cluster ===
 
@@ -154,7 +154,7 @@ qemu-img: Failed to turn zero into data clusters: Input/output error
 
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 qcow2: Marking image as corrupt: Refblock offset 0x22a00 unaligned (reftable index: 0); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 === Testing non-fatal corruption on freeing ===
 
@@ -171,8 +171,8 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qcow2: Image is corrupt: Cluster allocation offset 0x52a00 unaligned (L2 offset: 0x40000, L2 index: 0); further non-fatal corruption events will be suppressed
-read failed: Input/output error
-read failed: Input/output error
+qemu-io: read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Testing non-fatal and then fatal corruption report ===
 
@@ -181,15 +181,15 @@ wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qcow2: Image is corrupt: Cannot free unaligned cluster 0x52a00; further non-fatal corruption events will be suppressed
 qcow2: Marking image as corrupt: Cluster allocation offset 0x62a00 unaligned (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
+qemu-io: read failed: Input/output error
 discard 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Input/output error
 
 === Testing empty refcount table ===
 
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with refcount table); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 ERROR cluster 0 refcount=0 reference=1
 ERROR cluster 1 refcount=0 reference=1
 ERROR cluster 3 refcount=0 reference=1
@@ -209,7 +209,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qcow2: Marking image as corrupt: Preventing invalid allocation of refcount block at offset 0; further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 ERROR cluster 0 refcount=0 reference=1
 ERROR cluster 1 refcount=0 reference=1
 ERROR cluster 3 refcount=0 reference=1
@@ -229,7 +229,7 @@ No errors were found on the image.
 
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 qcow2: Marking image as corrupt: Preventing invalid allocation of L2 table at offset 0; further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 ERROR cluster 0 refcount=0 reference=1
 ERROR cluster 1 refcount=0 reference=1
 ERROR cluster 2 refcount=0 reference=1
@@ -251,7 +251,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 65536/65536 bytes at offset 65536
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qcow2: Marking image as corrupt: Preventing invalid allocation of compressed cluster at offset 0; further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 ERROR cluster 0 refcount=0 reference=1
 ERROR cluster 1 refcount=0 reference=1
 ERROR cluster 2 refcount=0 reference=1
@@ -286,7 +286,7 @@ No errors were found on the image.
 
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 qcow2: Marking image as corrupt: Preventing invalid allocation of L2 table at offset 0; further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 === Testing dirty corrupt image ===
 
@@ -319,7 +319,7 @@ wrote 65536/65536 bytes at offset 0
 discard 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qcow2: Marking image as corrupt: Preallocated zero cluster offset 0x2a00 unaligned (guest offset: 0); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 --- Repairing ---
 Repairing offset=2a00: Preallocated cluster is not properly aligned; L2 entry corrupted.
 The following inconsistencies were found and repaired:
@@ -337,7 +337,7 @@ wrote 131072/131072 bytes at offset 0
 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qcow2: Marking image as corrupt: Refblock offset 0x2a00 unaligned (reftable index: 0); further corruption events will be suppressed
 qcow2_free_clusters failed: Input/output error
-discard failed: No medium found
+qemu-io: discard failed: No medium found
 --- Repairing ---
 ERROR refcount block 0 is not cluster aligned; refcount table entry corrupted
 qcow2: Marking image as corrupt: Refblock offset 0x2a00 unaligned (reftable index: 0); further corruption events will be suppressed
@@ -419,8 +419,7 @@ qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps
 QMP_VERSION
 {"return": {}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "none0", "msg": "Preventing invalid write on metadata (overlaps with refcount table)", "offset": 65536, "node-name": "drive", "fatal": true, "size": 65536}}
-write failed: Input/output error
-{"return": ""}
+{"return": "Error: write failed: Input/output error\r\n"}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
 {"return": {}}
 
@@ -431,7 +430,6 @@ QMP_VERSION
 {"return": {}}
 qcow2: Image is corrupt: L2 table offset 0x2a2a2a00 unaligned (L1 index: 0); further non-fatal corruption events will be suppressed
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "", "msg": "L2 table offset 0x2a2a2a00 unaligned (L1 index: 0)", "node-name": "drive", "fatal": false}}
-{"return": ""}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
 {"return": {}}
 
diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out
index a2923b05c297..f2d015d8ccae 100644
--- a/tests/qemu-iotests/071.out
+++ b/tests/qemu-iotests/071.out
@@ -30,11 +30,11 @@ blkverify: read offset=0 bytes=512 contents mismatch at offset 0
 
 === Testing blkdebug through filename ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Testing blkdebug through file blockref ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Testing blkdebug on existing block device ===
 
@@ -43,8 +43,7 @@ QMP_VERSION
 {"return": {}}
 {"return": {}}
 {"return": {}}
-read failed: Input/output error
-{"return": ""}
+{"return": "Error: read failed: Input/output error\r\n"}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
 {"return": {}}
 
@@ -82,8 +81,7 @@ read 512/512 bytes at offset 0
 wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 {"return": ""}
-read failed: Input/output error
-{"return": ""}
+{"return": "Error: read failed: Input/output error\r\n"}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
 QEMU_PROG: Failed to flush the L2 table cache: Input/output error
 QEMU_PROG: Failed to flush the refcount block cache: Input/output error
diff --git a/tests/qemu-iotests/072.out b/tests/qemu-iotests/072.out
index fe949d47817a..d7ce24da1f7a 100644
--- a/tests/qemu-iotests/072.out
+++ b/tests/qemu-iotests/072.out
@@ -15,7 +15,7 @@ read 512/512 bytes at offset 512
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 read 512/512 bytes at offset 1024
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Pattern verification failed at offset 0, 512 bytes
+qemu-io: Pattern verification failed at offset 0, 512 bytes
 read 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 *** done
diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out
index d8acb3e72355..b20c21faf6a9 100644
--- a/tests/qemu-iotests/080.out
+++ b/tests/qemu-iotests/080.out
@@ -66,8 +66,8 @@ wrote 512/512 bytes at offset 0
 qemu-img: Failed to load snapshot: Snapshot L1 table offset invalid
 qemu-img: Snapshot L1 table offset invalid
 qemu-img: Failed to turn zero into data clusters: Invalid argument
+qemu-io: write failed: Invalid argument
 qemu-io: Failed to flush the refcount block cache: Invalid argument
-write failed: Invalid argument
 qemu-img: Snapshot L1 table offset invalid
 qemu-img: Could not apply snapshot 'test': Failed to load snapshot: Invalid argument
 qemu-img: Could not delete snapshot 'test': Snapshot L1 table offset invalid
@@ -89,8 +89,8 @@ wrote 512/512 bytes at offset 0
 qemu-img: Failed to load snapshot: Snapshot L1 table too large
 qemu-img: Snapshot L1 table too large
 qemu-img: Failed to turn zero into data clusters: File too large
+qemu-io: write failed: File too large
 qemu-io: Failed to flush the refcount block cache: File too large
-write failed: File too large
 qemu-img: Snapshot L1 table too large
 qemu-img: Could not apply snapshot 'test': Failed to load snapshot: File too large
 qemu-img: Could not delete snapshot 'test': Snapshot L1 table too large
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
index aba85ea56446..bc902bd81832 100644
--- a/tests/qemu-iotests/081.out
+++ b/tests/qemu-iotests/081.out
@@ -81,7 +81,7 @@ wrote 10485760/10485760 bytes at offset 0
 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 == checking that quorum is broken ==
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 == checking the blkverify mode with broken content ==
 quorum: offset=0 bytes=10485760 contents mismatch at offset 0
diff --git a/tests/qemu-iotests/083.out b/tests/qemu-iotests/083.out
index 2090ee693c16..a1c446d5365e 100644
--- a/tests/qemu-iotests/083.out
+++ b/tests/qemu-iotests/083.out
@@ -41,7 +41,7 @@ qemu-io: can't open device nbd+tcp://127.0.0.1:PORT/foo
 
 === Check disconnect after neg2 ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect 8 neg2 ===
 
@@ -53,31 +53,31 @@ qemu-io: can't open device nbd+tcp://127.0.0.1:PORT/foo
 
 === Check disconnect before request ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect after request ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect before reply ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect after reply ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect 4 reply ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect 8 reply ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect before data ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect after data ===
 
@@ -106,7 +106,7 @@ qemu-io: can't open device nbd+tcp://127.0.0.1:PORT/
 
 === Check disconnect after neg-classic ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect before neg1 ===
 
@@ -150,7 +150,7 @@ qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
 
 === Check disconnect after neg2 ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect 8 neg2 ===
 
@@ -162,31 +162,31 @@ qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
 
 === Check disconnect before request ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect after request ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect before reply ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect after reply ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect 4 reply ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect 8 reply ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect before data ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Check disconnect after data ===
 
@@ -215,6 +215,6 @@ qemu-io: can't open device nbd+unix:///?socket=SOCK_DIR/nbd.sock
 
 === Check disconnect after neg-classic ===
 
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 *** done
diff --git a/tests/qemu-iotests/089.out b/tests/qemu-iotests/089.out
index c53fc4823a16..a29e19b12d7e 100644
--- a/tests/qemu-iotests/089.out
+++ b/tests/qemu-iotests/089.out
@@ -16,7 +16,7 @@ read 512/512 bytes at offset 512
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 read 512/512 bytes at offset 1024
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Pattern verification failed at offset 0, 512 bytes
+qemu-io: Pattern verification failed at offset 0, 512 bytes
 read 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
@@ -33,7 +33,7 @@ read 512/512 bytes at offset 0
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 wrote 512/512 bytes at offset 229376
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 === Testing qemu-img info output ===
 
diff --git a/tests/qemu-iotests/114.out b/tests/qemu-iotests/114.out
index f51dd9d20a10..80220e440eca 100644
--- a/tests/qemu-iotests/114.out
+++ b/tests/qemu-iotests/114.out
@@ -11,7 +11,7 @@ cluster_size: 65536
 backing file: TEST_DIR/t.IMGFMT.base
 backing file format: foo
 qemu-io: can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknown driver 'foo'
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 read 4096/4096 bytes at offset 0
 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qemu-img: Could not change the backing file to 'TEST_DIR/t.qcow2.base': backing format must be specified
diff --git a/tests/qemu-iotests/134.out b/tests/qemu-iotests/134.out
index 4abc5b5f7da6..ce2a0df166ee 100644
--- a/tests/qemu-iotests/134.out
+++ b/tests/qemu-iotests/134.out
@@ -24,7 +24,7 @@ read 134217728/134217728 bytes at offset 0
 128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 == verify pattern failure with wrong password ==
-Pattern verification failed at offset 0, 134217728 bytes
+qemu-io: Pattern verification failed at offset 0, 134217728 bytes
 read 134217728/134217728 bytes at offset 0
 128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 *** done
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
index e19df5b6ba82..1947c1a1bd7c 100644
--- a/tests/qemu-iotests/137.out
+++ b/tests/qemu-iotests/137.out
@@ -40,5 +40,5 @@ OK: Dirty bit not set
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 qemu-io: Parameter 'lazy-refcounts' expects 'on' or 'off'
 qcow2: Marking image as corrupt: Preventing invalid allocation of L2 table at offset 0; further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 *** done
diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out
index 28e1a22952b6..e235d9e59e35 100644
--- a/tests/qemu-iotests/153.out
+++ b/tests/qemu-iotests/153.out
@@ -33,12 +33,12 @@ Is another process using the image [TEST_DIR/t.qcow2]?
 _qemu_io_wrapper -c open  TEST_DIR/t.qcow2 -c read 0 512
 qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
 Is another process using the image [TEST_DIR/t.qcow2]?
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 
 _qemu_io_wrapper -c open -r  TEST_DIR/t.qcow2 -c read 0 512
 qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
 Is another process using the image [TEST_DIR/t.qcow2]?
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 
 _qemu_img_wrapper info TEST_DIR/t.qcow2
 qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock
@@ -107,7 +107,7 @@ _qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
 
 _qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
 qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 
 _qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
 
@@ -176,7 +176,7 @@ _qemu_io_wrapper -r -c read 0 512 TEST_DIR/t.qcow2
 _qemu_io_wrapper -c open  TEST_DIR/t.qcow2 -c read 0 512
 qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
 Is another process using the image [TEST_DIR/t.qcow2]?
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 
 _qemu_io_wrapper -c open -r  TEST_DIR/t.qcow2 -c read 0 512
 
@@ -231,7 +231,7 @@ _qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
 
 _qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
 qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 
 _qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
 
@@ -336,7 +336,7 @@ _qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
 
 _qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
 qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 
 _qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
 
diff --git a/tests/qemu-iotests/171 b/tests/qemu-iotests/171
index d1d77f701304..87a8aa24d967 100755
--- a/tests/qemu-iotests/171
+++ b/tests/qemu-iotests/171
@@ -188,7 +188,7 @@ img_offset=512
 img_size=512
 _make_test_img $size
 (
-$QEMU_IO "$(img_json)"  <<EOT
+$QEMU_IO "$(img_json)" 2>&1 <<EOT
 write -P 0x0a 0 512
 write -P 0x0a 511 1
 write -P 0x0a 512 1
diff --git a/tests/qemu-iotests/171.out b/tests/qemu-iotests/171.out
index ec3363b4f440..67ef9b884152 100644
--- a/tests/qemu-iotests/171.out
+++ b/tests/qemu-iotests/171.out
@@ -21,32 +21,32 @@ wrote 1/1 bytes at offset 3583
 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 write across image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 write at image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 write after image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 writev before/after image boundary
-writev failed: Input/output error
+qemu-io: writev failed: Input/output error
 
 read before image boundary
 read 1/1 bytes at offset 3583
 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 read across image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 read at image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 read after image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 readv before/after image boundary
-readv failed: Input/output error
+qemu-io: readv failed: Input/output error
 
 fill image with pattern
 wrote 4096/4096 bytes at offset 0
@@ -60,7 +60,7 @@ read 4/4 bytes at offset 510
 4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 write zeroes across image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 write zeroes at image boundary and check
 wrote 2/2 bytes at offset 3582
@@ -68,7 +68,7 @@ wrote 2/2 bytes at offset 3582
 00000ffe:  00 00  ..
 read 2/2 bytes at offset 4094
 2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 fill image with pattern
 wrote 4096/4096 bytes at offset 0
@@ -82,7 +82,7 @@ read 4/4 bytes at offset 510
 4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 discard across image boundary
-discard failed: Input/output error
+qemu-io: discard failed: Input/output error
 
 discard at image boundary and check
 discard 2/2 bytes at offset 3582
@@ -90,7 +90,7 @@ discard 2/2 bytes at offset 3582
 00000ffe:  00 00  ..
 read 2/2 bytes at offset 4094
 2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 == test 'offset' and 'size' options ==
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4096
@@ -113,32 +113,32 @@ wrote 1/1 bytes at offset 2047
 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 write across image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 write at image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 write after image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 writev before/after image boundary
-writev failed: Input/output error
+qemu-io: writev failed: Input/output error
 
 read before image boundary
 read 1/1 bytes at offset 2047
 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 read across image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 read at image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 read after image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 readv before/after image boundary
-readv failed: Input/output error
+qemu-io: readv failed: Input/output error
 
 fill image with pattern
 wrote 4096/4096 bytes at offset 0
@@ -152,7 +152,7 @@ read 4/4 bytes at offset 510
 4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 write zeroes across image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 write zeroes at image boundary and check
 wrote 2/2 bytes at offset 2046
@@ -176,7 +176,7 @@ read 4/4 bytes at offset 510
 4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 discard across image boundary
-discard failed: Input/output error
+qemu-io: discard failed: Input/output error
 
 discard at image boundary and check
 discard 2/2 bytes at offset 2046
@@ -209,32 +209,32 @@ wrote 1/1 bytes at offset 2047
 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 write across image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 write at image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 write after image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 writev before/after image boundary
-writev failed: Input/output error
+qemu-io: writev failed: Input/output error
 
 read before image boundary
 read 1/1 bytes at offset 2047
 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 read across image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 read at image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 read after image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 readv before/after image boundary
-readv failed: Input/output error
+qemu-io: readv failed: Input/output error
 
 fill image with pattern
 wrote 4096/4096 bytes at offset 0
@@ -248,7 +248,7 @@ read 4/4 bytes at offset 8
 4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 write zeroes across image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 write zeroes at image boundary and check
 wrote 2/2 bytes at offset 2046
@@ -272,7 +272,7 @@ read 4/4 bytes at offset 8
 4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
 discard across image boundary
-discard failed: Input/output error
+qemu-io: discard failed: Input/output error
 
 discard at image boundary and check
 discard 2/2 bytes at offset 2046
@@ -290,12 +290,12 @@ wrote 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 1/1 bytes at offset 511
 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 wrote 1024/1024 bytes at offset 0
 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 1/1 bytes at offset 1023
 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 checking boundaries
 000001fe:  00 00 0a 0a  ....
 read 4/4 bytes at offset 510
diff --git a/tests/qemu-iotests/205 b/tests/qemu-iotests/205
index 78459065418c..3ed3ed233ac9 100755
--- a/tests/qemu-iotests/205
+++ b/tests/qemu-iotests/205
@@ -75,7 +75,7 @@ class TestNbdServerRemove(iotests.QMPTestCase):
 
     def assertReadFailed(self, qemu_io_output):
         self.assertEqual(filter_qemu_io(qemu_io_output).strip(),
-                         'read failed: Input/output error')
+                         'qemu-io: read failed: Input/output error')
 
     def assertConnectFailed(self, qemu_io_output):
         self.assertEqual(filter_qemu_io(qemu_io_output).strip(),
diff --git a/tests/qemu-iotests/214.out b/tests/qemu-iotests/214.out
index 9fc67287f8e1..26056938ee9e 100644
--- a/tests/qemu-iotests/214.out
+++ b/tests/qemu-iotests/214.out
@@ -7,7 +7,7 @@ wrote 2097152/2097152 bytes at offset 0
 2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 2097152/2097152 bytes at offset 2097152
 2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 No errors were found on the image.
 read 4194304/4194304 bytes at offset 0
 4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/220.out b/tests/qemu-iotests/220.out
index 33b994b8a14b..6f200ec89479 100644
--- a/tests/qemu-iotests/220.out
+++ b/tests/qemu-iotests/220.out
@@ -38,7 +38,7 @@ wrote 2097152/2097152 bytes at offset 37748736
 No errors were found on the image.
 image size 39845888
 == Trying to write compressed cluster ==
-write failed: File too large
+qemu-io: write failed: File too large
 image size 562949957615616
 == Writing normal cluster ==
 wrote 2097152/2097152 bytes at offset 0
diff --git a/tests/qemu-iotests/225.out b/tests/qemu-iotests/225.out
index 0998ae094c2b..beb8c23bd330 100644
--- a/tests/qemu-iotests/225.out
+++ b/tests/qemu-iotests/225.out
@@ -14,11 +14,11 @@ read 512/512 bytes at offset 0
 
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qemu-io overlay "read 0 512"
-read failed: Invalid argument
+Error: read failed: Invalid argument
 
 === Testing non-VMDK backing image ===
 
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qemu-io overlay "read 0 512"
-read failed: Invalid argument
+Error: read failed: Invalid argument
 *** done
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
index c62f5aec25b9..c5e62146c930 100644
--- a/tests/qemu-iotests/244.out
+++ b/tests/qemu-iotests/244.out
@@ -10,22 +10,22 @@ read 65536/65536 bytes at offset 0
 read 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qemu-io: can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 
 Data file required, but without data file name in the image:
 qemu-io: can't open device TEST_DIR/t.qcow2: 'data-file' is required for this image
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 read 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 qemu-io: can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 
 Setting data-file for an image with internal data:
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 qemu-io: can't open device TEST_DIR/t.qcow2: 'data-file' can only be set for images with an external data file
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 qemu-io: can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
 
 === Conflicting features ===
 
@@ -37,7 +37,7 @@ qemu-img: error while writing at byte 0: Operation not supported
 
 Convert uncompressed, then write compressed data manually:
 Images are identical.
-write failed: Operation not supported
+qemu-io: write failed: Operation not supported
 No errors were found on the image.
 
 Take an internal snapshot:
diff --git a/tests/qemu-iotests/249.out b/tests/qemu-iotests/249.out
index d2bf9be85ea2..3d37709a9ef8 100644
--- a/tests/qemu-iotests/249.out
+++ b/tests/qemu-iotests/249.out
@@ -9,7 +9,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 
 { 'execute': 'human-monitor-command',
        'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}}
-{"return": "Block node is read-onlyrn"}
+{"return": "Error: Block node is read-onlyrn"}
 
 === Run block-commit on base using an invalid filter node name
 
@@ -24,7 +24,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 
 { 'execute': 'human-monitor-command',
        'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}}
-{"return": "Block node is read-onlyrn"}
+{"return": "Error: Block node is read-onlyrn"}
 
 === Run block-commit on base using the default filter node name
 
@@ -43,5 +43,5 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 
 { 'execute': 'human-monitor-command',
        'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}}
-{"return": "Block node is read-onlyrn"}
+{"return": "Error: Block node is read-onlyrn"}
 *** done
diff --git a/tests/qemu-iotests/271.out b/tests/qemu-iotests/271.out
index 0b24d501595b..da92d4b5b1ab 100644
--- a/tests/qemu-iotests/271.out
+++ b/tests/qemu-iotests/271.out
@@ -456,7 +456,7 @@ L2 entry #0: 0x8000000000050001 0000000000000001
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
 L2 entry #1: 0x8000000000060000 00000001ffffffff
 qcow2: Marking image as corrupt: Invalid cluster entry found  (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 ### Corrupted L2 entries - read test (unallocated) ###
 
@@ -471,14 +471,14 @@ L2 entry #0: 0x0000000000000001 0000000000000000
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
 L2 entry #0: 0x0000000000000000 0000000000000001
 qcow2: Marking image as corrupt: Invalid cluster entry found  (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 # Both 'subcluster is zero' and 'subcluster is allocated' bits set
 
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
 L2 entry #1: 0x0000000000000000 0000000100000001
 qcow2: Marking image as corrupt: Invalid cluster entry found  (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 ### Compressed cluster with subcluster bitmap != 0 - read test ###
 
@@ -501,7 +501,7 @@ L2 entry #0: 0x8000000000050001 0000000000000001
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
 L2 entry #1: 0x8000000000060000 00000001ffffffff
 qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 ### Corrupted L2 entries - write test (unallocated) ###
 
@@ -516,14 +516,14 @@ L2 entry #0: 0x8000000000060000 0000000000000001
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
 L2 entry #0: 0x0000000000000000 0000000000000001
 qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 # Both 'subcluster is zero' and 'subcluster is allocated' bits set
 
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
 L2 entry #1: 0x0000000000000000 0000000100000001
 qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 ### Compressed cluster with subcluster bitmap != 0 - write test ###
 
@@ -555,7 +555,7 @@ Double checking the fixed image now...
 1 errors were found on the image.
 Data may be corrupted, or further writes to the image may corrupt it.
 qcow2: Marking image as corrupt: Cluster allocation offset 0x50200 unaligned (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 # Corrupted L2 entry, no allocated subclusters #
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
 Repairing offset=50200: Preallocated cluster is not properly aligned; L2 entry corrupted.
diff --git a/tests/qemu-iotests/289.out b/tests/qemu-iotests/289.out
index e54e2629d4dc..58e4f4942f0c 100644
--- a/tests/qemu-iotests/289.out
+++ b/tests/qemu-iotests/289.out
@@ -3,6 +3,6 @@ QA output created by 289
 === Avoid freeing external data clusters on failure ===
 
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536 data_file=TEST_DIR/t.IMGFMT.data_file
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 No errors were found on the image.
 *** done
diff --git a/tests/qemu-iotests/305.out b/tests/qemu-iotests/305.out
index 538019e72601..af09d6a3ff48 100644
--- a/tests/qemu-iotests/305.out
+++ b/tests/qemu-iotests/305.out
@@ -12,5 +12,5 @@ discard 1024/1024 bytes at offset 125952
 ### Corrupt the offset of the second refcount block
 ### Try to allocate the discarded clusters again
 qcow2: Marking image as corrupt: Refblock offset 0x20600 unaligned (reftable index: 0x1); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 *** done
diff --git a/tests/qemu-iotests/307.out b/tests/qemu-iotests/307.out
index a9b37d3ac119..608b407a6fc5 100644
--- a/tests/qemu-iotests/307.out
+++ b/tests/qemu-iotests/307.out
@@ -127,7 +127,7 @@ exports available: 1
 {"error": {"class": "GenericError", "desc": "export 'export1' still in use"}}
 {"execute": "block-export-del", "arguments": {"id": "export1", "mode": "hard"}}
 {"return": {}}
-read failed: Input/output error
+qemu-io: read failed: Input/output error
 
 {"execute": "query-block-exports", "arguments": {}}
 {"return": []}
diff --git a/tests/qemu-iotests/tests/backup-discard-source b/tests/qemu-iotests/tests/backup-discard-source
index 17fef9c6d34d..6c624bc8b0b0 100755
--- a/tests/qemu-iotests/tests/backup-discard-source
+++ b/tests/qemu-iotests/tests/backup-discard-source
@@ -87,11 +87,11 @@ class TestBackup(iotests.QMPTestCase):
 
     def tearDown(self):
         # That should fail, because region is discarded
-        self.vm.hmp_qemu_io('access', 'read 0 1M')
+        result = self.vm.hmp_qemu_io('access', 'read 0 1M')
 
         self.vm.shutdown()
 
-        self.assertTrue('read failed: Permission denied' in self.vm.get_log())
+        self.assertIn('read failed: Permission denied', result['return'])
 
         # Final check that temp image is empty
         mapping = qemu_img_map(temp_img)
diff --git a/tests/qemu-iotests/tests/copy-before-write b/tests/qemu-iotests/tests/copy-before-write
index 236cb8ac3744..3e43e7127f20 100755
--- a/tests/qemu-iotests/tests/copy-before-write
+++ b/tests/qemu-iotests/tests/copy-before-write
@@ -87,17 +87,17 @@ class TestCbwError(iotests.QMPTestCase):
 
         result = self.vm.qmp('human-monitor-command',
                              command_line='qemu-io cbw "write 0 1M"')
-        self.assert_qmp(result, 'return', '')
+        write_res = result['return']
 
         result = self.vm.qmp('human-monitor-command',
                              command_line='qemu-io access "read 0 1M"')
-        self.assert_qmp(result, 'return', '')
+        read_res = result['return']
 
         self.vm.shutdown()
         log = self.vm.get_log()
         log = iotests.filter_qtest(log)
         log = iotests.filter_qemu_io(log)
-        return log
+        return log, write_res, read_res
 
     def do_cbw_error_via_blockdev_backup(self, on_cbw_error=None):
         self.vm.cmd('blockdev-add', {
@@ -150,28 +150,29 @@ class TestCbwError(iotests.QMPTestCase):
 
         result = self.vm.qmp('human-monitor-command',
                              command_line='qemu-io cbw "write 0 1M"')
-        self.assert_qmp(result, 'return', '')
+        write_res = result['return']
 
         result = self.vm.qmp('human-monitor-command',
                              command_line='qemu-io access "read 0 1M"')
-        self.assert_qmp(result, 'return', '')
+        read_res = result['return']
 
         self.vm.shutdown()
         log = self.vm.get_log()
         log = iotests.filter_qemu_io(log)
-        return log
+        return log, write_res, read_res
 
     def test_break_snapshot_on_cbw_error(self):
         """break-snapshot behavior:
         Guest write succeed, but further snapshot-read fails, as snapshot is
         broken.
         """
-        log = self.do_cbw_error('break-snapshot')
+        log, write_res, read_res = self.do_cbw_error('break-snapshot')
+        self.assertEqual(write_res, '')
+        self.assertIn('read failed: Permission denied', read_res)
 
         self.assertEqual(log, """\
 wrote 1048576/1048576 bytes at offset 0
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Permission denied
 """)
 
     def test_break_guest_write_on_cbw_error(self):
@@ -179,10 +180,11 @@ read failed: Permission denied
         Guest write fails, but snapshot-access continues working and further
         snapshot-read succeeds.
         """
-        log = self.do_cbw_error('break-guest-write')
+        log, write_res, read_res = self.do_cbw_error('break-guest-write')
+        self.assertIn('write failed: Input/output error', write_res)
+        self.assertEqual(read_res, '')
 
         self.assertEqual(log, """\
-write failed: Input/output error
 read 1048576/1048576 bytes at offset 0
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 """)
@@ -191,20 +193,24 @@ read 1048576/1048576 bytes at offset 0
         """Ensure CBW filter accepts break-snapshot policy
         specified in blockdev-backup QMP command.
         """
-        log = self.do_cbw_error_via_blockdev_backup('break-snapshot')
+        log, write_res, read_res = \
+            self.do_cbw_error_via_blockdev_backup('break-snapshot')
+        self.assertEqual(write_res, '')
+        self.assertIn('read failed: Permission denied', read_res)
         self.assertEqual(log, """\
 wrote 1048576/1048576 bytes at offset 0
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Permission denied
 """)
 
     def test_break_guest_write_policy_forwarding(self):
         """Ensure CBW filter accepts break-guest-write policy
         specified in blockdev-backup QMP command.
         """
-        log = self.do_cbw_error_via_blockdev_backup('break-guest-write')
+        log, write_res, read_res = \
+            self.do_cbw_error_via_blockdev_backup('break-guest-write')
+        self.assertIn('write failed: Input/output error', write_res)
+        self.assertEqual(read_res, '')
         self.assertEqual(log, """\
-write failed: Input/output error
 read 1048576/1048576 bytes at offset 0
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 """)
@@ -213,9 +219,11 @@ read 1048576/1048576 bytes at offset 0
         """Ensure break-guest-write policy is used by default when
         on-cbw-error is not explicitly specified.
         """
-        log = self.do_cbw_error_via_blockdev_backup()
+        log, write_res, read_res = \
+            self.do_cbw_error_via_blockdev_backup()
+        self.assertIn('write failed: Input/output error', write_res)
+        self.assertEqual(read_res, '')
         self.assertEqual(log, """\
-write failed: Input/output error
 read 1048576/1048576 bytes at offset 0
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 """)
@@ -260,47 +268,53 @@ read 1048576/1048576 bytes at offset 0
 
         result = self.vm.qmp('human-monitor-command',
                              command_line='qemu-io cbw "write 0 512K"')
-        self.assert_qmp(result, 'return', '')
+        write1_res = result['return']
 
         # We need second write to trigger throttling
         result = self.vm.qmp('human-monitor-command',
                              command_line='qemu-io cbw "write 512K 512K"')
-        self.assert_qmp(result, 'return', '')
+        write2_res = result['return']
 
         result = self.vm.qmp('human-monitor-command',
                              command_line='qemu-io access "read 0 1M"')
-        self.assert_qmp(result, 'return', '')
+        read_res = result['return']
 
         self.vm.shutdown()
         log = self.vm.get_log()
         log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log)
         log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log)
         log = iotests.filter_qemu_io(log)
-        return log
+        return log, write1_res, write2_res, read_res
 
     def test_timeout_break_guest(self):
-        log = self.do_cbw_timeout('break-guest-write')
+        log, write1_res, write2_res, read_res = \
+            self.do_cbw_timeout('break-guest-write')
+        self.assertEqual(write1_res, '')
         # macOS and FreeBSD tend to represent ETIMEDOUT as
         # "Operation timed out", when Linux prefer
         # "Connection timed out"
-        log = log.replace('Operation timed out',
-                          'Connection timed out')
+        write2_res = write2_res.replace('Operation timed out',
+                                        'Connection timed out')
+        self.assertIn('write failed: Connection timed out', write2_res)
+        self.assertEqual(read_res, '')
         self.assertEqual(log, """\
 wrote 524288/524288 bytes at offset 0
 512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Connection timed out
 read 1048576/1048576 bytes at offset 0
 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 """)
 
     def test_timeout_break_snapshot(self):
-        log = self.do_cbw_timeout('break-snapshot')
+        log, write1_res, write2_res, read_res = \
+            self.do_cbw_timeout('break-snapshot')
+        self.assertEqual(write1_res, '')
+        self.assertEqual(write2_res, '')
+        self.assertIn('read failed: Permission denied', read_res)
         self.assertEqual(log, """\
 wrote 524288/524288 bytes at offset 0
 512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 524288/524288 bytes at offset 524288
 512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Permission denied
 """)
 
 
diff --git a/tests/qemu-iotests/tests/file-io-error.out b/tests/qemu-iotests/tests/file-io-error.out
index 0f46455a94a7..bf8c0018ba5a 100644
--- a/tests/qemu-iotests/tests/file-io-error.out
+++ b/tests/qemu-iotests/tests/file-io-error.out
@@ -21,7 +21,7 @@ QA output created by file-io-error
       }}
 {"return": {}}
 
-write failed: Input/output error
+qemu-io: write failed: Input/output error
 
 {'execute': 'block-export-del',
       'arguments': {'id': 'exp0'}}
diff --git a/tests/qemu-iotests/tests/image-fleecing.out b/tests/qemu-iotests/tests/image-fleecing.out
index acfc89ff0e99..dc788f1e20a4 100644
--- a/tests/qemu-iotests/tests/image-fleecing.out
+++ b/tests/qemu-iotests/tests/image-fleecing.out
@@ -238,13 +238,13 @@ read -P0xd5 1M 64k
 read -P0xdc 32M 64k
 read -P0xcd 0x3ff0000 64k
 read -P0 0x00f8000 32k
-read failed: Invalid argument
+qemu-io: read failed: Invalid argument
 
 read -P0 0x2010000 32k
-read failed: Invalid argument
+qemu-io: read failed: Invalid argument
 
 read -P0 0x3fe0000 64k
-read failed: Invalid argument
+qemu-io: read failed: Invalid argument
 
 
 --- Testing COW ---
@@ -265,13 +265,13 @@ read -P0xd5 1M 64k
 read -P0xdc 32M 64k
 read -P0xcd 0x3ff0000 64k
 read -P0 0x00f8000 32k
-read failed: Invalid argument
+qemu-io: read failed: Invalid argument
 
 read -P0 0x2010000 32k
-read failed: Invalid argument
+qemu-io: read failed: Invalid argument
 
 read -P0 0x3fe0000 64k
-read failed: Invalid argument
+qemu-io: read failed: Invalid argument
 
 
 --- Cleanup ---
diff --git a/tests/qemu-iotests/tests/inactive-node-nbd.out b/tests/qemu-iotests/tests/inactive-node-nbd.out
index a458b4fc0552..0fb8c18d8748 100644
--- a/tests/qemu-iotests/tests/inactive-node-nbd.out
+++ b/tests/qemu-iotests/tests/inactive-node-nbd.out
@@ -215,13 +215,13 @@ target-fmt active: True
 read 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 
-write failed: Operation not permitted
+qemu-io: write failed: Operation not permitted
 
-write failed: Operation not permitted
+qemu-io: write failed: Operation not permitted
 
-write failed: Operation not permitted
+qemu-io: write failed: Operation not permitted
 
-discard failed: Operation not permitted
+qemu-io: discard failed: Operation not permitted
 
 
 qemu-io: Failed to get allocation status: Operation not permitted

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 21/49] block: add x-qemu-io QMP command
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (19 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 20/49] qemu-io: propagate errors through Error API instead of printf Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 22/49] qtest: add qemu-io command to the qtest protocol Marc-André Lureau
                   ` (27 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Kevin Wolf,
	Hanna Reitz, Eric Blake, qemu-block

Add an x-qemu-io QMP command that runs qemu-io commands on block
devices. The command accepts a device name (block backend name,
node-name, or qdev ID) and a qemu-io command string.

Refactor hmp_qemu_io() to be a thin wrapper around the new QMP
command, following the standard HMP-over-QMP pattern used by other
block commands.

This change is also required for the qtest qemu-io command in the
following patch.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 block/monitor/block-hmp-cmds.c | 60 ++------------------------------
 block/monitor/meson.build      |  1 +
 block/monitor/qmp-cmds.c       | 79 ++++++++++++++++++++++++++++++++++++++++++
 qapi/block.json                | 34 ++++++++++++++++++
 4 files changed, 117 insertions(+), 57 deletions(-)

diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index 9930620a4a16..22fa03089ea3 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -56,7 +56,6 @@
 #include "block/qapi.h"
 #include "block/block_int.h"
 #include "block/block-hmp-cmds.h"
-#include "qemu-io.h"
 
 static void hmp_drive_add_node(Monitor *mon, const char *optstr)
 {
@@ -541,67 +540,14 @@ void hmp_eject(Monitor *mon, const QDict *qdict)
 
 void hmp_qemu_io(Monitor *mon, const QDict *qdict)
 {
-    BlockBackend *blk = NULL;
-    BlockDriverState *bs = NULL;
-    BlockBackend *local_blk = NULL;
     bool qdev = qdict_get_try_bool(qdict, "qdev", false);
     const char *device = qdict_get_str(qdict, "device");
     const char *command = qdict_get_str(qdict, "command");
     Error *err = NULL;
-    int ret;
 
-    if (qdev) {
-        blk = blk_by_qdev_id(device, &err);
-        if (!blk) {
-            goto fail;
-        }
-    } else {
-        blk = blk_by_name(device);
-        if (!blk) {
-            bs = bdrv_lookup_bs(NULL, device, &err);
-            if (!bs) {
-                goto fail;
-            }
-        }
-    }
-
-    if (bs) {
-        blk = local_blk = blk_new(bdrv_get_aio_context(bs), 0, BLK_PERM_ALL);
-        ret = blk_insert_bs(blk, bs, &err);
-        if (ret < 0) {
-            goto fail;
-        }
-    }
-
-    /*
-     * Notably absent: Proper permission management. This is sad, but it seems
-     * almost impossible to achieve without changing the semantics and thereby
-     * limiting the use cases of the qemu-io HMP command.
-     *
-     * In an ideal world we would unconditionally create a new BlockBackend for
-     * qemuio_command(), but we have commands like 'reopen' and want them to
-     * take effect on the exact BlockBackend whose name the user passed instead
-     * of just on a temporary copy of it.
-     *
-     * Another problem is that deleting the temporary BlockBackend involves
-     * draining all requests on it first, but some qemu-iotests cases want to
-     * issue multiple aio_read/write requests and expect them to complete in
-     * the background while the monitor has already returned.
-     *
-     * This is also what prevents us from saving the original permissions and
-     * restoring them later: We can't revoke permissions until all requests
-     * have completed, and we don't know when that is nor can we really let
-     * anything else run before we have revoken them to avoid race conditions.
-     *
-     * What happens now is that command() in qemu-io-cmds.c can extend the
-     * permissions if necessary for the qemu-io command. And they simply stay
-     * extended, possibly resulting in a read-only guest device keeping write
-     * permissions. Ugly, but it appears to be the lesser evil.
-     */
-    qemuio_command(blk, command, &err);
-
-fail:
-    blk_unref(local_blk);
+    qmp_x_qemu_io(qdev ? NULL : device,
+                  qdev ? device : NULL,
+                  command, &err);
     hmp_handle_error(mon, err);
 }
 
diff --git a/block/monitor/meson.build b/block/monitor/meson.build
index 1022516e93c5..74faced9e17f 100644
--- a/block/monitor/meson.build
+++ b/block/monitor/meson.build
@@ -1,2 +1,3 @@
 system_ss.add(files('block-hmp-cmds.c'))
 block_ss.add(files('bitmap-qmp-cmds.c'))
+system_ss.add(files('qmp-cmds.c'))
diff --git a/block/monitor/qmp-cmds.c b/block/monitor/qmp-cmds.c
new file mode 100644
index 000000000000..e5759d824f13
--- /dev/null
+++ b/block/monitor/qmp-cmds.c
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "qemu/osdep.h"
+
+#include "system/block-backend.h"
+#include "block/block_int.h"
+#include "qapi/qapi-commands-block.h"
+#include "qapi/error.h"
+#include "qemu-io.h"
+
+void qmp_x_qemu_io(const char *device, const char *qdev,
+                   const char *command, Error **errp)
+{
+    BlockBackend *blk = NULL;
+    BlockBackend *local_blk = NULL;
+    BlockDriverState *bs = NULL;
+    int ret;
+
+    if (!device && !qdev) {
+        error_setg(errp, "Must specify either device or qdev");
+        return;
+    }
+    if (qdev && device) {
+        error_setg(errp, "Cannot specify both qdev and device");
+        return;
+    }
+
+    if (qdev) {
+        blk = blk_by_qdev_id(qdev, errp);
+        if (!blk) {
+            return;
+        }
+    } else {
+        blk = blk_by_name(device);
+        if (!blk) {
+            bs = bdrv_lookup_bs(NULL, device, errp);
+            if (!bs) {
+                return;
+            }
+        }
+    }
+
+    if (bs) {
+        blk = local_blk = blk_new(bdrv_get_aio_context(bs), 0, BLK_PERM_ALL);
+        ret = blk_insert_bs(blk, bs, errp);
+        if (ret < 0) {
+            goto fail;
+        }
+    }
+
+    /*
+     * Notably absent: Proper permission management. This is sad, but it seems
+     * almost impossible to achieve without changing the semantics and thereby
+     * limiting the use cases of the qemu-io command.
+     *
+     * In an ideal world we would unconditionally create a new BlockBackend for
+     * qemuio_command(), but we have commands like 'reopen' and want them to
+     * take effect on the exact BlockBackend whose name the user passed instead
+     * of just on a temporary copy of it.
+     *
+     * Another problem is that deleting the temporary BlockBackend involves
+     * draining all requests on it first, but some qemu-iotests cases want to
+     * issue multiple aio_read/write requests and expect them to complete in
+     * the background while the monitor has already returned.
+     *
+     * This is also what prevents us from saving the original permissions and
+     * restoring them later: We can't revoke permissions until all requests
+     * have completed, and we don't know when that is nor can we really let
+     * anything else run before we have revoken them to avoid race conditions.
+     *
+     * What happens now is that command() in qemu-io-cmds.c can extend the
+     * permissions if necessary for the qemu-io command. And they simply stay
+     * extended, possibly resulting in a read-only guest device keeping write
+     * permissions. Ugly, but it appears to be the lesser evil.
+     */
+    qemuio_command(blk, command, errp);
+
+fail:
+    blk_unref(local_blk);
+}
diff --git a/qapi/block.json b/qapi/block.json
index 46955bbb3e34..012a9d73333b 100644
--- a/qapi/block.json
+++ b/qapi/block.json
@@ -603,3 +603,37 @@
            '*boundaries-zap': ['uint64'],
            '*boundaries-flush': ['uint64'] },
   'allow-preconfig': true }
+
+##
+# @x-qemu-io:
+#
+# Run a qemu-io command on a block device.  Take either a block
+# backend name or a qdev ID to identify the device.
+#
+# @device: the block backend name, node-name to run the
+#     command on.
+#
+# @qdev: the qdev ID of the block device to run the
+#     command on.
+#
+# @command: the qemu-io command string to execute.
+#
+# Features:
+#
+# @unstable: This command is for testing only.
+#
+# Since: 11.2
+#
+# .. qmp-example::
+#
+#     -> { "execute": "x-qemu-io",
+#          "arguments": { "device": "virtio0",
+#                         "command": "read 0 512" } }
+#     <- { "return": {} }
+##
+{ 'command': 'x-qemu-io',
+  'data': { '*device': 'str',
+            '*qdev': 'str',
+            'command': 'str' },
+  'features': [ 'unstable' ],
+  'allow-preconfig': true }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 22/49] qtest: add qemu-io command to the qtest protocol
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (20 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 21/49] block: add x-qemu-io QMP command Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 23/49] qtest/ide-test: convert to use qtest qemu-io command Marc-André Lureau
                   ` (26 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Fabiano Rosas,
	Laurent Vivier, Paolo Bonzini

Add a "qemu-io" command to the qtest protocol so that tests can issue
block layer I/O commands without going through the HMP monitor's
"human-monitor-command" QMP, or use QMP at all.

Unfortunately, many tests will prefer to use QMP as they also monitor
and log other events. It's easier if it is pipelined in the same stream.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 system/qtest.c         | 14 ++++++++++++++
 tests/qtest/libqtest.c | 14 ++++++++++++++
 tests/qtest/libqtest.h | 11 +++++++++++
 3 files changed, 39 insertions(+)

diff --git a/system/qtest.c b/system/qtest.c
index cf3012391774..47c954838dd0 100644
--- a/system/qtest.c
+++ b/system/qtest.c
@@ -33,6 +33,7 @@
 #include "qom/object_interfaces.h"
 #include "qom/qom-qobject.h"
 #include "qobject/qobject.h"
+#include "qapi-commands-block.h"
 
 #define MAX_IRQ 256
 
@@ -797,6 +798,19 @@ static void qtest_process_command(CharFrontend *chr, gchar **words)
         }
         g_slist_free(list);
         qtest_send(chr, "OK\n");
+    } else if (strcmp(words[0], "qemu-io") == 0) {
+        const char *io_dev;
+        g_autofree char *io_cmd = NULL;
+        Error *err = NULL;
+
+        g_assert(words[1] && words[2]);
+        io_dev = words[1];
+        io_cmd = g_strjoinv(" ", &words[2]);
+
+        qmp_x_qemu_io(io_dev, NULL, io_cmd, &err);
+        qtest_sendf(chr, err ? "FAIL %s\n" : "OK\n",
+                    err ? error_get_pretty(err) : NULL);
+        error_free(err);
     } else if (process_command_cb && process_command_cb(chr, words)) {
         /* Command got consumed by the callback handler */
     } else {
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index c33c799c92d1..5e7b26e49ef9 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -1012,6 +1012,20 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...)
     return ret;
 }
 
+void qtest_qemu_io(QTestState *s, const char *device,
+                   const char *fmt, ...)
+{
+    va_list ap;
+    g_autofree char *cmd = NULL;
+
+    va_start(ap, fmt);
+    cmd = g_strdup_vprintf(fmt, ap);
+    va_end(ap);
+
+    qtest_sendf(s, "qemu-io %s %s\n", device, cmd);
+    qtest_rsp(s);
+}
+
 const char *qtest_get_arch(void)
 {
     /*
diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
index 45217fb8dc09..58491ca53ab7 100644
--- a/tests/qtest/libqtest.h
+++ b/tests/qtest/libqtest.h
@@ -424,6 +424,17 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
 char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap)
     G_GNUC_PRINTF(2, 0);
 
+/**
+ * qtest_qemu_io:
+ * @s: #QTestState instance to operate on.
+ * @device: block device node-name or BlockBackend name.
+ * @fmt: qemu-io command to send, formats arguments like sprintf().
+ *
+ * Send a qemu-io command via the qtest protocol.
+ */
+void qtest_qemu_io(QTestState *s, const char *device,
+                   const char *fmt, ...) G_GNUC_PRINTF(3, 4);
+
 void qtest_module_load(QTestState *s, const char *prefix, const char *libname);
 
 /**

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 23/49] qtest/ide-test: convert to use qtest qemu-io command
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (21 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 22/49] qtest: add qemu-io command to the qtest protocol Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:54   ` Denis V. Lunev
  2026-08-16 19:12 ` [PATCH v3 24/49] tests/qemu-iotests: add qmp_qemu_io() Marc-André Lureau
                   ` (25 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, John Snow,
	Denis V. Lunev, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	qemu-block

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/qtest/ahci-test.c | 5 ++---
 tests/qtest/ide-test.c  | 4 ++--
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/tests/qtest/ahci-test.c b/tests/qtest/ahci-test.c
index 71d23fe56af7..0528a422fafc 100644
--- a/tests/qtest/ahci-test.c
+++ b/tests/qtest/ahci-test.c
@@ -1719,8 +1719,7 @@ static void test_atapi_engine_restart_in_flight(bool dma)
     qtest_memset(ahci->parent->qts, buffer, 0x00, ATAPI_SECTOR_SIZE);
 
     /* Suspend the next backend read so the ATAPI read stays in flight. */
-    g_free(qtest_hmp(ahci->parent->qts,
-                     "qemu-io drive0 \"break read_aio rd\""));
+    qtest_qemu_io(ahci->parent->qts, "drive0", "break read_aio rd");
 
     cmd = ahci_atapi_command_create(CMD_ATAPI_READ_10, ATAPI_SECTOR_SIZE,
                                     dma);
@@ -1732,7 +1731,7 @@ static void test_atapi_engine_restart_in_flight(bool dma)
     ahci_px_clr(ahci, port, AHCI_PX_CMD, AHCI_PX_CMD_ST);
     ahci_px_set(ahci, port, AHCI_PX_CMD, AHCI_PX_CMD_ST);
 
-    g_free(qtest_hmp(ahci->parent->qts, "qemu-io drive0 \"resume rd\""));
+    qtest_qemu_io(ahci->parent->qts, "drive0", "resume rd");
 
     /* Round-trip through the device to confirm qemu is still alive. */
     ahci_px_rreg(ahci, port, AHCI_PX_TFD);
diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c
index b36b0f8875b2..31692f6925ac 100644
--- a/tests/qtest/ide-test.c
+++ b/tests/qtest/ide-test.c
@@ -836,7 +836,7 @@ static void test_flush(void)
     make_dirty(qts, 0);
 
     /* Delay the completion of the flush request until we explicitly do it */
-    g_free(qtest_hmp(qts, "qemu-io ide0-hd0 \"break flush_to_os A\""));
+    qtest_qemu_io(qts, "ide0-hd0", "break flush_to_os A");
 
     /* FLUSH CACHE command on device 0*/
     qpci_io_writeb(dev, ide_bar, reg_device, 0);
@@ -848,7 +848,7 @@ static void test_flush(void)
     assert_bit_clear(data, DF | ERR | DRQ);
 
     /* Complete the command */
-    g_free(qtest_hmp(qts, "qemu-io ide0-hd0 \"resume A\""));
+    qtest_qemu_io(qts, "ide0-hd0", "resume A");
 
     /* Check registers */
     data = qpci_io_readb(dev, ide_bar, reg_device);

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 24/49] tests/qemu-iotests: add qmp_qemu_io()
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (22 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 23/49] qtest/ide-test: convert to use qtest qemu-io command Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 25/49] tests/qemu-iotests: convert pause/resume_drive() to QMP Marc-André Lureau
                   ` (24 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Kevin Wolf,
	Hanna Reitz, qemu-block

Add qmp_qemu_io() method as a QMP counterpart to hmp_qemu_io(),
using the x-qemu-io QMP command instead of human-monitor-command.
The x-qemu-io command takes separate 'device' (or 'qdev') and
'command' arguments, and returns the error string.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
---
 tests/qemu-iotests/iotests.py | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 072be80e0792..c24f1e3767c4 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -953,6 +953,20 @@ def hmp_qemu_io(self, drive: str, cmd: str,
         d = '-d ' if qdev else ''
         return self.hmp(f'qemu-io {d}{drive} "{cmd}"', use_log=use_log)
 
+    def qmp_qemu_io(self, drive: str, cmd: str,
+                    use_log: bool = False, qdev: bool = False) -> str:
+        """Write to a given drive using the x-qemu-io QMP command"""
+        kwargs: Dict[str, Any] = {'command': cmd}
+        if qdev:
+            kwargs['qdev'] = drive
+        else:
+            kwargs['device'] = drive
+        if use_log:
+            res = self.qmp_log('x-qemu-io', **kwargs)
+        else:
+            res = self.qmp('x-qemu-io', **kwargs)
+        return res.get('error', {}).get('desc', '')
+
     def flatten_qmp_object(self, obj, output=None, basestr=''):
         if output is None:
             output = {}

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 25/49] tests/qemu-iotests: convert pause/resume_drive() to QMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (23 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 24/49] tests/qemu-iotests: add qmp_qemu_io() Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 26/49] build-sys: add 'hmp' option Marc-André Lureau
                   ` (23 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Kevin Wolf,
	Hanna Reitz, qemu-block

Convert pause_drive() and resume_drive() to use x-qemu-io directly
instead of routing through hmp().

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 tests/qemu-iotests/iotests.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index c24f1e3767c4..f36bcf316429 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -941,11 +941,11 @@ def pause_drive(self, drive: str, event: Optional[str] = None) -> None:
             self.pause_drive(drive, "read_aio")
             self.pause_drive(drive, "write_aio")
             return
-        self.hmp(f'qemu-io {drive} "break {event} bp_{drive}"')
+        self.qmp_qemu_io(drive, f'break {event} bp_{drive}')
 
     def resume_drive(self, drive: str) -> None:
         """Resume drive r/w operations"""
-        self.hmp(f'qemu-io {drive} "remove_break bp_{drive}"')
+        self.qmp_qemu_io(drive, f'remove_break bp_{drive}')
 
     def hmp_qemu_io(self, drive: str, cmd: str,
                     use_log: bool = False, qdev: bool = False) -> QMPMessage:

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 26/49] build-sys: add 'hmp' option
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (24 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 25/49] tests/qemu-iotests: convert pause/resume_drive() to QMP Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 27/49] monitor: reject readline monitor when HMP is disabled Marc-André Lureau
                   ` (22 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Paolo Bonzini,
	Pierrick Bouvier, Alex Bennée

Add an option to enable/disable HMP support, default to true. The
following commits are going to make --disable-hmp gradually work.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 meson.build                   | 4 ++++
 meson_options.txt             | 2 ++
 scripts/meson-buildoptions.sh | 3 +++
 3 files changed, 9 insertions(+)

diff --git a/meson.build b/meson.build
index 49a5baf5b52f..03b334549f23 100644
--- a/meson.build
+++ b/meson.build
@@ -247,6 +247,9 @@ have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_
 
 have_tcg = get_option('tcg').allowed() and (have_system or have_user)
 
+have_hmp = get_option('hmp') \
+  .disable_auto_if(not have_system) \
+  .allowed()
 have_tools = get_option('tools') \
   .disable_auto_if(not have_system) \
   .allowed()
@@ -2266,6 +2269,7 @@ endif
 config_host_data = configuration_data()
 
 config_host_data.set('CONFIG_HAVE_RUST', have_rust)
+config_host_data.set('CONFIG_HMP', have_hmp)
 audio_drivers_selected = []
 if have_system
   audio_drivers_available = {
diff --git a/meson_options.txt b/meson_options.txt
index a07cb47d35e9..d8f59cf92cae 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -111,6 +111,8 @@ option('cfi', type: 'boolean', value: false,
        description: 'Control-Flow Integrity (CFI)')
 option('cfi_debug', type: 'boolean', value: false,
        description: 'Verbose errors in case of CFI violation')
+option('hmp', type : 'feature', value : 'auto',
+       description: 'HMP monitor support')
 option('multiprocess', type: 'feature', value: 'auto',
        description: 'Out of process device emulation support')
 option('relocatable', type : 'boolean', value : true,
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index c003985047c0..5a67e59a1671 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -125,6 +125,7 @@ meson_options_help() {
   printf "%s\n" '  gtk             GTK+ user interface'
   printf "%s\n" '  guest-agent     Build QEMU Guest Agent'
   printf "%s\n" '  guest-agent-msi Build MSI package for the QEMU Guest Agent'
+  printf "%s\n" '  hmp             HMP monitor support'
   printf "%s\n" '  hv-balloon      hv-balloon driver (requires Glib 2.68+ GTree API)'
   printf "%s\n" '  hvf             HVF acceleration support'
   printf "%s\n" '  iconv           Font glyph conversion support'
@@ -339,6 +340,8 @@ _meson_option_parse() {
     --disable-guest-agent-msi) printf "%s" -Dguest_agent_msi=disabled ;;
     --enable-hexagon-idef-parser) printf "%s" -Dhexagon_idef_parser=true ;;
     --disable-hexagon-idef-parser) printf "%s" -Dhexagon_idef_parser=false ;;
+    --enable-hmp) printf "%s" -Dhmp=enabled ;;
+    --disable-hmp) printf "%s" -Dhmp=disabled ;;
     --enable-hv-balloon) printf "%s" -Dhv_balloon=enabled ;;
     --disable-hv-balloon) printf "%s" -Dhv_balloon=disabled ;;
     --enable-hvf) printf "%s" -Dhvf=enabled ;;

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 27/49] monitor: reject readline monitor when HMP is disabled
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (25 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 26/49] build-sys: add 'hmp' option Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 20:23   ` Dr. David Alan Gilbert
  2026-08-16 19:12 ` [PATCH v3 28/49] system: guard HMP initialization paths with CONFIG_HMP Marc-André Lureau
                   ` (21 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Dr. David Alan Gilbert

When QEMU is built without HMP support, reject '-monitor' (which
requests readline/HMP mode) early in monitor_new_opts() with a
clear error message directing users to '-qmp' instead.

Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
---
 monitor/monitor.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/monitor/monitor.c b/monitor/monitor.c
index 6d6ffbb0f78a..8528af6f79b8 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -776,6 +776,16 @@ int monitor_new_opts(QemuOpts *opts, Error **errp)
     MonitorOptions *options;
     int ret;
 
+#ifndef CONFIG_HMP
+    const char *mode = qemu_opt_get(opts, "mode");
+    /* readline is HMP..  */
+    if (mode && g_str_equal(mode, "readline")) {
+        error_setg(errp, "HMP monitor is not available,"
+                   " use '-qmp' instead of '-monitor'");
+        return -1;
+    }
+#endif
+
     v = opts_visitor_new(opts);
     visit_type_MonitorOptions(v, NULL, &options, errp);
     visit_free(v);

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 28/49] system: guard HMP initialization paths with CONFIG_HMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (26 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 27/49] monitor: reject readline monitor when HMP is disabled Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 29/49] tests: skip HMP-dependent tests when HMP is disabled Marc-André Lureau
                   ` (20 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Paolo Bonzini,
	Alex Bennée

- disable default monitor when HMP is not available
- hide 'readline' from -mon help text
- error out on mux chardev monitor when no HMP
- skip HMP monitor terminal for gdb, return E01 for 'qRcmd' remote
  commands

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 chardev/char.c   | 9 ++++++++-
 gdbstub/system.c | 8 ++++++++
 qemu-options.hx  | 6 +++++-
 system/vl.c      | 4 ++++
 4 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/chardev/char.c b/chardev/char.c
index 22e5bae388ad..c6c8133f5c1d 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -804,8 +804,9 @@ static Chardev *qemu_chr_new_from_name(const char *label, const char *filename,
     }
 
     if (qemu_opt_get_bool(opts, "mux", 0)) {
-        const char *chardev_id = qemu_opts_id(opts);
         assert(permit_mux_mon);
+#ifdef CONFIG_HMP
+        const char *chardev_id = qemu_opts_id(opts);
         monitor_new_hmp(NULL, chardev_id, true, &err);
         if (err) {
             error_report_err(err);
@@ -813,6 +814,12 @@ static Chardev *qemu_chr_new_from_name(const char *label, const char *filename,
             chr = NULL;
             goto out;
         }
+#else
+        error_report("HMP monitor is disabled");
+        object_unparent(OBJECT(chr));
+        chr = NULL;
+        goto out;
+#endif
     }
 
 out:
diff --git a/gdbstub/system.c b/gdbstub/system.c
index c77d067ab458..070bc26f416c 100644
--- a/gdbstub/system.c
+++ b/gdbstub/system.c
@@ -387,10 +387,14 @@ bool gdbserver_start(const char *device, Error **errp)
 
         qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
 
+#ifdef CONFIG_HMP
         /* Initialize a monitor terminal for gdb */
         mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
                                    NULL, NULL, &error_abort);
         monitor_new_hmp(NULL, mon_chr->label, false, &error_abort);
+#else
+        mon_chr = NULL;
+#endif
     } else {
         qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
         mon_chr = gdbserver_system_state.mon_chr;
@@ -524,10 +528,14 @@ void gdb_handle_query_rcmd(GArray *params, void *ctx)
     len = len / 2;
     gdb_hextomem(gdbserver_state.mem_buf, gdb_get_cmd_param(params, 0)->data, len);
     g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
+#ifdef CONFIG_HMP
     qemu_chr_be_write(gdbserver_system_state.mon_chr,
                       gdbserver_state.mem_buf->data,
                       gdbserver_state.mem_buf->len);
     gdb_put_packet("OK");
+#else
+    gdb_put_packet("E01");
+#endif
 }
 
 /*
diff --git a/qemu-options.hx b/qemu-options.hx
index 34970fffc94b..680344162efb 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4985,7 +4985,11 @@ SRST
 ERST
 
 DEF("mon", HAS_ARG, QEMU_OPTION_mon, \
-    "-mon [chardev=]name[,mode=readline|control][,pretty=on|off]\n", QEMU_ARCH_ALL)
+    "-mon [chardev=]name[,mode="
+#ifdef CONFIG_HMP
+    "readline|"
+#endif
+    "control][,pretty=on|off]\n", QEMU_ARCH_ALL)
 SRST
 ``-mon [chardev=]name[,mode=readline|control][,pretty=on|off]``
     Set up a monitor connected to the chardev ``name``.
diff --git a/system/vl.c b/system/vl.c
index 5ccc19282ba2..760cf6e7265a 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -199,7 +199,11 @@ static int has_defaults = 1;
 static int default_audio = 1;
 static int default_serial = 1;
 static int default_parallel = 1;
+#ifdef CONFIG_HMP
 static int default_monitor = 1;
+#else
+static int default_monitor; /* false */
+#endif
 static int default_floppy = 1;
 static int default_cdrom = 1;
 static bool auto_create_sdcard = true;

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 29/49] tests: skip HMP-dependent tests when HMP is disabled
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (27 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 28/49] system: guard HMP initialization paths with CONFIG_HMP Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 19:12 ` [PATCH v3 30/49] monitor: isolate HMP declarations in hmp.h Marc-André Lureau
                   ` (19 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Kevin Wolf,
	Hanna Reitz, Hyman Huang, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, qemu-block

Add runtime detection of HMP availability so tests gracefully skip
instead of failing when QEMU is built without HMP support.

For qtests (drive_del-test), use compile-time #ifndef CONFIG_HMP guards.

For bash iotests, add _require_hmp() to common.rc that probes QEMU.

For Python iotests, add _verify_hmp() and a require_hmp parameter
threaded through execute_setup_common()/main()/script_initialize()/
script_main().

An earlier version of this series did an almost-complete conversion of
the tests to QMP. However, this made the series even longer. I decided
to post-pone it for now.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
---
 tests/qemu-iotests/028                             |  1 +
 tests/qemu-iotests/045                             |  3 ++-
 tests/qemu-iotests/051                             |  1 +
 tests/qemu-iotests/056                             |  3 ++-
 tests/qemu-iotests/060                             |  1 +
 tests/qemu-iotests/068                             |  1 +
 tests/qemu-iotests/071                             |  1 +
 tests/qemu-iotests/081                             |  1 +
 tests/qemu-iotests/091                             |  1 +
 tests/qemu-iotests/093                             |  3 ++-
 tests/qemu-iotests/102                             |  1 +
 tests/qemu-iotests/117                             |  1 +
 tests/qemu-iotests/119                             |  1 +
 tests/qemu-iotests/120                             |  1 +
 tests/qemu-iotests/124                             |  3 ++-
 tests/qemu-iotests/130                             |  1 +
 tests/qemu-iotests/132                             |  3 ++-
 tests/qemu-iotests/136                             |  3 ++-
 tests/qemu-iotests/142                             |  1 +
 tests/qemu-iotests/145                             |  1 +
 tests/qemu-iotests/146                             |  1 +
 tests/qemu-iotests/148                             |  3 ++-
 tests/qemu-iotests/151                             |  3 ++-
 tests/qemu-iotests/152                             |  3 ++-
 tests/qemu-iotests/153                             |  1 +
 tests/qemu-iotests/156                             |  1 +
 tests/qemu-iotests/157                             |  1 +
 tests/qemu-iotests/161                             |  1 +
 tests/qemu-iotests/165                             |  3 ++-
 tests/qemu-iotests/172                             |  1 +
 tests/qemu-iotests/181                             |  1 +
 tests/qemu-iotests/185                             |  1 +
 tests/qemu-iotests/186                             |  1 +
 tests/qemu-iotests/192                             |  1 +
 tests/qemu-iotests/201                             |  1 +
 tests/qemu-iotests/216                             |  3 ++-
 tests/qemu-iotests/225                             |  1 +
 tests/qemu-iotests/232                             |  1 +
 tests/qemu-iotests/236                             |  3 ++-
 tests/qemu-iotests/245                             |  3 ++-
 tests/qemu-iotests/246                             |  3 ++-
 tests/qemu-iotests/249                             |  1 +
 tests/qemu-iotests/254                             |  3 ++-
 tests/qemu-iotests/255                             |  3 ++-
 tests/qemu-iotests/257                             |  3 ++-
 tests/qemu-iotests/260                             |  3 ++-
 tests/qemu-iotests/264                             |  3 ++-
 tests/qemu-iotests/267                             |  1 +
 tests/qemu-iotests/274                             |  3 ++-
 tests/qemu-iotests/280                             |  1 +
 tests/qemu-iotests/281                             |  3 ++-
 tests/qemu-iotests/283                             |  1 +
 tests/qemu-iotests/286                             |  1 +
 tests/qemu-iotests/298                             |  3 ++-
 tests/qemu-iotests/300                             |  3 ++-
 tests/qemu-iotests/304                             |  3 ++-
 tests/qemu-iotests/310                             |  3 ++-
 tests/qemu-iotests/common.rc                       |  8 +++++++
 tests/qemu-iotests/iotests.py                      | 14 +++++++++++-
 tests/qemu-iotests/tests/backup-discard-source     |  3 ++-
 tests/qemu-iotests/tests/copy-before-write         |  3 ++-
 tests/qemu-iotests/tests/image-fleecing            |  3 ++-
 tests/qemu-iotests/tests/iothreads-create          |  3 ++-
 tests/qemu-iotests/tests/luks-detached-header      |  3 ++-
 .../tests/migrate-bitmaps-postcopy-test            |  3 ++-
 tests/qemu-iotests/tests/migrate-bitmaps-test      |  3 ++-
 tests/qemu-iotests/tests/mirror-change-copy-mode   |  3 ++-
 tests/qemu-iotests/tests/mirror-ready-cancel-error |  3 ++-
 tests/qemu-iotests/tests/qcow2-internal-snapshots  |  1 +
 tests/qemu-iotests/tests/qsd-migrate               |  3 ++-
 tests/qemu-iotests/tests/reopen-file               |  3 ++-
 tests/qemu-iotests/tests/write-zeroes-unmap        |  1 +
 tests/qtest/drive_del-test.c                       | 25 ++++++++++++++++++++++
 73 files changed, 152 insertions(+), 37 deletions(-)

diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028
index 2b232c461405..28f01439c525 100755
--- a/tests/qemu-iotests/028
+++ b/tests/qemu-iotests/028
@@ -49,6 +49,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 _supported_fmt qcow2 qed
 _supported_proto file fuse
 _supported_os Linux
+_require_hmp
 
 # Choose a size that is not necessarily a cluster size multiple for image
 # formats that use clusters.  This will ensure that the base image doesn't end
diff --git a/tests/qemu-iotests/045 b/tests/qemu-iotests/045
index a341f21cd70f..cd1b35edb17f 100755
--- a/tests/qemu-iotests/045
+++ b/tests/qemu-iotests/045
@@ -172,4 +172,5 @@ class TestSCMFd(iotests.QMPTestCase):
 
 if __name__ == '__main__':
     iotests.main(supported_fmts=['raw'],
-                 supported_protocols=['file'])
+                 supported_protocols=['file'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
index 4c079b11e320..a722c0c1bc8f 100755
--- a/tests/qemu-iotests/051
+++ b/tests/qemu-iotests/051
@@ -45,6 +45,7 @@ _supported_proto file
 _unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file \
     compression_type
 _require_drivers nbd
+_require_hmp
 
 if [ "$QEMU_DEFAULT_MACHINE" = "pc" ]; then
     _require_devices lsi53c895a
diff --git a/tests/qemu-iotests/056 b/tests/qemu-iotests/056
index 808ea6b48abe..7cc97486951c 100755
--- a/tests/qemu-iotests/056
+++ b/tests/qemu-iotests/056
@@ -332,4 +332,5 @@ class BackupTest(iotests.QMPTestCase):
 
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2', 'qed'],
-                 supported_protocols=['file'])
+                 supported_protocols=['file'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
index 5cd21a6f686f..8d06f84df16b 100755
--- a/tests/qemu-iotests/060
+++ b/tests/qemu-iotests/060
@@ -56,6 +56,7 @@ _unsupported_imgopts 'compat=0.10' data_file \
 
 # The repair process will create a large file - so check for availability first
 _require_large_file 64G
+_require_hmp
 
 rt_offset=65536  # 0x10000 (XXX: just an assumption)
 rb_offset=131072 # 0x20000 (XXX: just an assumption)
diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
index 7ecd2474093e..11b660a8b7c4 100755
--- a/tests/qemu-iotests/068
+++ b/tests/qemu-iotests/068
@@ -43,6 +43,7 @@ _supported_proto generic
 # Internal snapshots are (currently) impossible with refcount_bits=1,
 # and generally impossible with external data files
 _unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]' data_file
+_require_hmp
 
 IMG_SIZE=128K
 
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
index 331f8cfddcf9..83c4ce6314c5 100755
--- a/tests/qemu-iotests/071
+++ b/tests/qemu-iotests/071
@@ -43,6 +43,7 @@ _require_drivers blkdebug blkverify
 # blkdebug can only inject errors on bs->file, not on the data_file,
 # so this test does not work with external data files
 _unsupported_imgopts data_file
+_require_hmp
 
 do_run_qemu()
 {
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
index 1ac66f197e46..d9e729f674c6 100755
--- a/tests/qemu-iotests/081
+++ b/tests/qemu-iotests/081
@@ -44,6 +44,7 @@ _supported_proto file
 _supported_os Linux
 _require_drivers quorum
 _require_devices virtio-scsi
+_require_hmp
 
 do_run_qemu()
 {
diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
index e396748a9179..626203d6fc93 100755
--- a/tests/qemu-iotests/091
+++ b/tests/qemu-iotests/091
@@ -48,6 +48,7 @@ _supported_fmt qcow2
 _supported_proto file fuse
 _supported_os Linux
 _supported_cache_modes writethrough none writeback
+_require_hmp
 _default_cache_mode none writeback
 
 size=1G
diff --git a/tests/qemu-iotests/093 b/tests/qemu-iotests/093
index 4f9e224e8a8c..26ae6e2b2d56 100755
--- a/tests/qemu-iotests/093
+++ b/tests/qemu-iotests/093
@@ -419,4 +419,5 @@ class ThrottleTestRemovableMedia(iotests.QMPTestCase):
 if __name__ == '__main__':
     if 'null-co' not in iotests.supported_formats():
         iotests.notrun('null-co driver support missing')
-    iotests.main(supported_fmts=["raw"])
+    iotests.main(supported_fmts=["raw"],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/102 b/tests/qemu-iotests/102
index 141bfe1e9023..5db8180d3bb7 100755
--- a/tests/qemu-iotests/102
+++ b/tests/qemu-iotests/102
@@ -41,6 +41,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 
 _supported_fmt qcow2
 _supported_proto file fuse
+_require_hmp
 
 IMG_SIZE=64K
 
diff --git a/tests/qemu-iotests/117 b/tests/qemu-iotests/117
index 6081473584fe..5cc9433f4a67 100755
--- a/tests/qemu-iotests/117
+++ b/tests/qemu-iotests/117
@@ -41,6 +41,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 
 _supported_fmt qcow2
 _supported_proto file fuse
+_require_hmp
 
 _make_test_img 64k
 
diff --git a/tests/qemu-iotests/119 b/tests/qemu-iotests/119
index 6cac8793bac6..ce1b62521f59 100755
--- a/tests/qemu-iotests/119
+++ b/tests/qemu-iotests/119
@@ -41,6 +41,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 _supported_fmt raw
 _supported_proto nbd
 _supported_os Linux
+_require_hmp
 
 _make_test_img 64M
 # This should not crash
diff --git a/tests/qemu-iotests/120 b/tests/qemu-iotests/120
index ac7bd8c4e3cd..e4ed87e1a705 100755
--- a/tests/qemu-iotests/120
+++ b/tests/qemu-iotests/120
@@ -42,6 +42,7 @@ _supported_fmt generic
 _supported_proto file fuse
 _unsupported_fmt luks
 _require_drivers raw
+_require_hmp
 
 _make_test_img 64M
 
diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124
index b2f4328e3456..ab9ea4d8b59d 100755
--- a/tests/qemu-iotests/124
+++ b/tests/qemu-iotests/124
@@ -750,4 +750,5 @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
 
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2'],
-                 supported_protocols=['file'])
+                 supported_protocols=['file'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130
index 7af85d20a892..3d10aba2594e 100755
--- a/tests/qemu-iotests/130
+++ b/tests/qemu-iotests/130
@@ -46,6 +46,7 @@ _supported_proto file
 _supported_os Linux
 # We are going to use lazy-refcounts
 _unsupported_imgopts 'compat=0.10'
+_require_hmp
 
 qemu_comm_method="monitor"
 
diff --git a/tests/qemu-iotests/132 b/tests/qemu-iotests/132
index 12a64b3d95a3..3756573a57c0 100755
--- a/tests/qemu-iotests/132
+++ b/tests/qemu-iotests/132
@@ -57,4 +57,5 @@ class TestSingleDrive(iotests.QMPTestCase):
 
 if __name__ == '__main__':
     iotests.main(supported_fmts=['raw', 'qcow2'],
-                 supported_protocols=['file'])
+                 supported_protocols=['file'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/136 b/tests/qemu-iotests/136
index 58df876bafca..72fd638aa04d 100755
--- a/tests/qemu-iotests/136
+++ b/tests/qemu-iotests/136
@@ -410,4 +410,5 @@ class BlockDeviceStatsTestCoroutine(BlockDeviceStatsTestCase):
 if __name__ == '__main__':
     if 'null-co' not in iotests.supported_formats():
         iotests.notrun('null-co driver support missing')
-    iotests.main(supported_fmts=["raw"])
+    iotests.main(supported_fmts=["raw"],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/142 b/tests/qemu-iotests/142
index 86d65a2d1a1e..8538a727ac08 100755
--- a/tests/qemu-iotests/142
+++ b/tests/qemu-iotests/142
@@ -43,6 +43,7 @@ _supported_proto file
 # We test all cache modes anyway, but O_DIRECT needs to be supported
 _default_cache_mode none
 _supported_cache_modes none directsync
+_require_hmp
 
 do_run_qemu()
 {
diff --git a/tests/qemu-iotests/145 b/tests/qemu-iotests/145
index a2ce92516dc5..f61a50f63951 100755
--- a/tests/qemu-iotests/145
+++ b/tests/qemu-iotests/145
@@ -40,6 +40,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 
 _supported_fmt generic
 _supported_proto generic
+_require_hmp
 
 _make_test_img 1M
 
diff --git a/tests/qemu-iotests/146 b/tests/qemu-iotests/146
index 661a9d2625cc..f63291d0ffba 100755
--- a/tests/qemu-iotests/146
+++ b/tests/qemu-iotests/146
@@ -42,6 +42,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 _supported_fmt vpc
 _supported_proto file
 _supported_os Linux
+_require_hmp
 
 
 qemu_comm_method="monitor"
diff --git a/tests/qemu-iotests/148 b/tests/qemu-iotests/148
index 7ccbde4633c2..4b092dccb7cc 100755
--- a/tests/qemu-iotests/148
+++ b/tests/qemu-iotests/148
@@ -140,4 +140,5 @@ class TestFifoQuorumEvents(TestQuorumEvents):
 if __name__ == '__main__':
     iotests.verify_quorum()
     iotests.main(supported_fmts=["raw"],
-                 supported_protocols=["file"])
+                 supported_protocols=["file"],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/151 b/tests/qemu-iotests/151
index 647194094a4c..204221a5738e 100755
--- a/tests/qemu-iotests/151
+++ b/tests/qemu-iotests/151
@@ -434,4 +434,5 @@ class TestHighThrottledWithNbdExport(TestThrottledWithNbdExportBase):
 
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2', 'raw'],
-                 supported_protocols=['file'])
+                 supported_protocols=['file'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/152 b/tests/qemu-iotests/152
index 197bea9e7785..d9170359213a 100755
--- a/tests/qemu-iotests/152
+++ b/tests/qemu-iotests/152
@@ -61,4 +61,5 @@ class TestUnaligned(iotests.QMPTestCase):
 
 if __name__ == '__main__':
     iotests.main(supported_fmts=['raw', 'qcow2'],
-                 supported_protocols=['file'])
+                 supported_protocols=['file'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/153 b/tests/qemu-iotests/153
index 1e02f6a6e344..def01d6f3ea4 100755
--- a/tests/qemu-iotests/153
+++ b/tests/qemu-iotests/153
@@ -59,6 +59,7 @@ _check_ofd || _notrun "OFD lock not available"
 
 _supported_fmt qcow2
 _supported_proto file
+_require_hmp
 
 _run_cmd()
 {
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
index 97c2d86ce573..a0e4d1ffd42a 100755
--- a/tests/qemu-iotests/156
+++ b/tests/qemu-iotests/156
@@ -53,6 +53,7 @@ _supported_fmt qcow2 qed
 _supported_proto file
 # Copying files around with cp does not work with external data files
 _unsupported_imgopts data_file
+_require_hmp
 
 # Create source disk
 TEST_IMG="$TEST_IMG.backing" _make_test_img 1M
diff --git a/tests/qemu-iotests/157 b/tests/qemu-iotests/157
index aa2ebbfb4b43..531dbd3122b1 100755
--- a/tests/qemu-iotests/157
+++ b/tests/qemu-iotests/157
@@ -41,6 +41,7 @@ _supported_fmt generic
 _supported_proto file
 
 _require_devices virtio-blk
+_require_hmp
 
 do_run_qemu()
 {
diff --git a/tests/qemu-iotests/161 b/tests/qemu-iotests/161
index f25effab9360..8ca139262975 100755
--- a/tests/qemu-iotests/161
+++ b/tests/qemu-iotests/161
@@ -45,6 +45,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 _supported_fmt qcow2 qed
 _supported_proto file fuse
 _supported_os Linux
+_require_hmp
 
 IMG_SIZE=1M
 
diff --git a/tests/qemu-iotests/165 b/tests/qemu-iotests/165
index b3b1709d71fa..8fc79daae16d 100755
--- a/tests/qemu-iotests/165
+++ b/tests/qemu-iotests/165
@@ -154,4 +154,5 @@ class TestPersistentDirtyBitmap(iotests.QMPTestCase):
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2'],
                  supported_protocols=['file'],
-                 unsupported_imgopts=['compat'])
+                 unsupported_imgopts=['compat'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/172 b/tests/qemu-iotests/172
index 4da0e0f2e297..a78e42ff0adf 100755
--- a/tests/qemu-iotests/172
+++ b/tests/qemu-iotests/172
@@ -42,6 +42,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 _supported_fmt qcow2
 _supported_proto file
 _supported_os Linux
+_require_hmp
 
 if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
     _notrun "Requires a PC machine"
diff --git a/tests/qemu-iotests/181 b/tests/qemu-iotests/181
index b904e8ce0124..458cb737f1cb 100755
--- a/tests/qemu-iotests/181
+++ b/tests/qemu-iotests/181
@@ -47,6 +47,7 @@ _supported_fmt generic
 _unsupported_fmt qcow vdi vhdx vmdk vpc vvfat parallels
 _supported_proto generic
 _supported_os Linux
+_require_hmp
 
 _flaky_test https://gitlab.com/qemu-project/qemu/-/work_items/3515
 
diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185
index a62ae8d3293e..bb577a9cc999 100755
--- a/tests/qemu-iotests/185
+++ b/tests/qemu-iotests/185
@@ -50,6 +50,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 _supported_fmt qcow2
 _supported_proto file
 _supported_os Linux
+_require_hmp
 _flaky_test https://gitlab.com/qemu-project/qemu/-/issues/3270
 
 size=$((64 * 1048576))
diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186
index eaf13c7a3340..9a4215d28e92 100755
--- a/tests/qemu-iotests/186
+++ b/tests/qemu-iotests/186
@@ -41,6 +41,7 @@ _supported_fmt qcow2
 _supported_proto file fuse
 _require_drivers null-co
 _require_devices virtio-scsi-pci
+_require_hmp
 
 if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
     _notrun "Requires a PC machine"
diff --git a/tests/qemu-iotests/192 b/tests/qemu-iotests/192
index e66e1a4f06af..6869bd171537 100755
--- a/tests/qemu-iotests/192
+++ b/tests/qemu-iotests/192
@@ -43,6 +43,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 
 _supported_fmt generic
 _supported_proto file
+_require_hmp
 
 if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
     _notrun "Requires a PC machine"
diff --git a/tests/qemu-iotests/201 b/tests/qemu-iotests/201
index 1b8eb51d8f38..a5c750c38a83 100755
--- a/tests/qemu-iotests/201
+++ b/tests/qemu-iotests/201
@@ -47,6 +47,7 @@ _supported_os Linux
 # Internal snapshots are (currently) impossible with refcount_bits=1,
 # and generally impossible with external data files
 _unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
+_require_hmp
 
 size=64M
 _make_test_img $size
diff --git a/tests/qemu-iotests/216 b/tests/qemu-iotests/216
index 311e02af3a7b..4eabada9b35d 100755
--- a/tests/qemu-iotests/216
+++ b/tests/qemu-iotests/216
@@ -25,7 +25,8 @@ from iotests import log, qemu_img, qemu_io
 
 # Need backing file support
 iotests.script_initialize(supported_fmts=['qcow2', 'qcow', 'qed', 'vmdk'],
-                          supported_platforms=['linux'])
+                          supported_platforms=['linux'],
+                          require_hmp=True)
 
 log('')
 log('=== Copy-on-read across nodes ===')
diff --git a/tests/qemu-iotests/225 b/tests/qemu-iotests/225
index b5949fcb58e0..8128d583d609 100755
--- a/tests/qemu-iotests/225
+++ b/tests/qemu-iotests/225
@@ -46,6 +46,7 @@ _supported_os Linux
 _unsupported_imgopts "subformat=monolithicFlat" \
                      "subformat=twoGbMaxExtentFlat" \
                      "subformat=twoGbMaxExtentSparse"
+_require_hmp
 
 TEST_IMG="$TEST_IMG.base" _make_test_img 1M
 TEST_IMG="$TEST_IMG.not_base" _make_test_img 1M
diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232
index b30faaa21806..1ee0aae481d4 100755
--- a/tests/qemu-iotests/232
+++ b/tests/qemu-iotests/232
@@ -43,6 +43,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 _supported_fmt generic
 _supported_proto file
 _supported_os Linux
+_require_hmp
 
 do_run_qemu()
 {
diff --git a/tests/qemu-iotests/236 b/tests/qemu-iotests/236
index 20419bbb9e54..3cf0de4043f6 100755
--- a/tests/qemu-iotests/236
+++ b/tests/qemu-iotests/236
@@ -23,7 +23,8 @@
 import iotests
 from iotests import log
 
-iotests.script_initialize(supported_fmts=['generic'])
+iotests.script_initialize(supported_fmts=['generic'],
+                          require_hmp=True)
 size = 64 * 1024 * 1024
 granularity = 64 * 1024
 
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
index 03550b99715c..2f354d1d9205 100755
--- a/tests/qemu-iotests/245
+++ b/tests/qemu-iotests/245
@@ -1160,4 +1160,5 @@ class TestBlockdevReopen(iotests.QMPTestCase):
 if __name__ == '__main__':
     iotests.activate_logging()
     iotests.main(supported_fmts=["qcow2"],
-                 supported_protocols=["file"])
+                 supported_protocols=["file"],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/246 b/tests/qemu-iotests/246
index b009a7839775..cee5131c3ce4 100755
--- a/tests/qemu-iotests/246
+++ b/tests/qemu-iotests/246
@@ -24,7 +24,8 @@ import iotests
 from iotests import log
 
 iotests.script_initialize(supported_fmts=['qcow2'],
-                          unsupported_imgopts=['compat'])
+                          unsupported_imgopts=['compat'],
+                          require_hmp=True)
 size = 64 * 1024 * 1024 * 1024
 gran_small = 32 * 1024
 gran_large = 128 * 1024
diff --git a/tests/qemu-iotests/249 b/tests/qemu-iotests/249
index 28bffd4d5712..1254bf942913 100755
--- a/tests/qemu-iotests/249
+++ b/tests/qemu-iotests/249
@@ -45,6 +45,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 _supported_fmt qcow2 qed
 _supported_proto file fuse
 _supported_os Linux
+_require_hmp
 
 IMG_SIZE=1M
 
diff --git a/tests/qemu-iotests/254 b/tests/qemu-iotests/254
index 7ea098818cf0..d3d18a1bbf1f 100755
--- a/tests/qemu-iotests/254
+++ b/tests/qemu-iotests/254
@@ -23,7 +23,8 @@ import iotests
 from iotests import qemu_img_create, file_path, log
 
 iotests.script_initialize(supported_fmts=['qcow2'],
-                          unsupported_imgopts=['compat'])
+                          unsupported_imgopts=['compat'],
+                          require_hmp=True)
 
 disk, top = file_path('disk', 'top')
 size = 1024 * 1024
diff --git a/tests/qemu-iotests/255 b/tests/qemu-iotests/255
index 88b29d64b44e..8f88522f1e91 100755
--- a/tests/qemu-iotests/255
+++ b/tests/qemu-iotests/255
@@ -24,7 +24,8 @@
 import iotests
 from iotests import imgfmt
 
-iotests.script_initialize(supported_fmts=['qcow2'])
+iotests.script_initialize(supported_fmts=['qcow2'],
+                          require_hmp=True)
 
 iotests.log('Finishing a commit job with background reads')
 iotests.log('============================================')
diff --git a/tests/qemu-iotests/257 b/tests/qemu-iotests/257
index cd0468aaa162..5e4dba02e769 100755
--- a/tests/qemu-iotests/257
+++ b/tests/qemu-iotests/257
@@ -533,4 +533,5 @@ def main():
 
 if __name__ == '__main__':
     iotests.script_main(main, supported_fmts=['qcow2'],
-                        supported_protocols=['file'])
+                        supported_protocols=['file'],
+                        require_hmp=True)
diff --git a/tests/qemu-iotests/260 b/tests/qemu-iotests/260
index c2133f998010..65165446607c 100755
--- a/tests/qemu-iotests/260
+++ b/tests/qemu-iotests/260
@@ -24,7 +24,8 @@ from iotests import qemu_img_create, file_path, log, filter_qmp_event
 
 iotests.script_initialize(
     supported_fmts=['qcow2'],
-    unsupported_imgopts=['compat']
+    unsupported_imgopts=['compat'],
+    require_hmp=True,
 )
 
 base, top = file_path('base', 'top')
diff --git a/tests/qemu-iotests/264 b/tests/qemu-iotests/264
index c6ba2754e279..b621f11ab427 100755
--- a/tests/qemu-iotests/264
+++ b/tests/qemu-iotests/264
@@ -114,4 +114,5 @@ class TestNbdReconnect(iotests.QMPTestCase):
 
 
 if __name__ == '__main__':
-    iotests.main(supported_fmts=['qcow2'])
+    iotests.main(supported_fmts=['qcow2'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/267 b/tests/qemu-iotests/267
index 2e2afdad9c57..e14aeb1f18d0 100755
--- a/tests/qemu-iotests/267
+++ b/tests/qemu-iotests/267
@@ -48,6 +48,7 @@ _require_drivers copy-on-read
 _unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
 
 _require_devices virtio-blk
+_require_hmp
 
 do_run_qemu()
 {
diff --git a/tests/qemu-iotests/274 b/tests/qemu-iotests/274
index 2495e051a227..d91c11c70d2e 100755
--- a/tests/qemu-iotests/274
+++ b/tests/qemu-iotests/274
@@ -24,7 +24,8 @@ import iotests
 
 iotests.script_initialize(supported_fmts=['qcow2'],
                           supported_platforms=['linux'],
-                          unsupported_imgopts=['refcount_bits', 'compat'])
+                          unsupported_imgopts=['refcount_bits', 'compat'],
+                          require_hmp=True)
 
 size_short = 1 * 1024 * 1024
 size_long = 2 * 1024 * 1024
diff --git a/tests/qemu-iotests/280 b/tests/qemu-iotests/280
index 5f50500fdb82..8f4750de074b 100755
--- a/tests/qemu-iotests/280
+++ b/tests/qemu-iotests/280
@@ -27,6 +27,7 @@ iotests.script_initialize(
     supported_fmts=['qcow2'],
     supported_protocols=['file'],
     supported_platforms=['linux'],
+    require_hmp=True,
 )
 
 with iotests.FilePath('base') as base_path , \
diff --git a/tests/qemu-iotests/281 b/tests/qemu-iotests/281
index f6746a12e881..5f3050f50d0b 100755
--- a/tests/qemu-iotests/281
+++ b/tests/qemu-iotests/281
@@ -336,4 +336,5 @@ class TestYieldingAndTimers(iotests.QMPTestCase):
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2'],
                  supported_protocols=['file'],
-                 unsupported_imgopts=['compat'])
+                 unsupported_imgopts=['compat'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/283 b/tests/qemu-iotests/283
index 5defe48e97d5..6d341d3e9745 100755
--- a/tests/qemu-iotests/283
+++ b/tests/qemu-iotests/283
@@ -24,6 +24,7 @@ import iotests
 # The test is unrelated to formats, restrict it to qcow2 to avoid extra runs
 iotests.script_initialize(
     supported_fmts=['qcow2'],
+    require_hmp=True,
 )
 
 size = 1024 * 1024
diff --git a/tests/qemu-iotests/286 b/tests/qemu-iotests/286
index cc6aacf02283..3b030ec58aa0 100755
--- a/tests/qemu-iotests/286
+++ b/tests/qemu-iotests/286
@@ -40,6 +40,7 @@ _supported_proto file fuse
 # Internal snapshots are (currently) impossible with refcount_bits=1,
 # and generally impossible with external data files
 _unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
+_require_hmp
 
 _make_test_img 64M
 
diff --git a/tests/qemu-iotests/298 b/tests/qemu-iotests/298
index 09c9290711a8..f2b94077f43a 100755
--- a/tests/qemu-iotests/298
+++ b/tests/qemu-iotests/298
@@ -177,4 +177,5 @@ class TestTruncate(iotests.QMPTestCase):
 
 
 if __name__ == '__main__':
-    iotests.main(supported_fmts=['qcow2'], required_fmts=['preallocate'])
+    iotests.main(supported_fmts=['qcow2'], required_fmts=['preallocate'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/300 b/tests/qemu-iotests/300
index e46616d7b19a..df2ba326327d 100755
--- a/tests/qemu-iotests/300
+++ b/tests/qemu-iotests/300
@@ -683,4 +683,5 @@ class TestAliasTransformMigration(TestDirtyBitmapMigration):
         self.verify_dest_error(None)
 
 if __name__ == '__main__':
-    iotests.main(supported_protocols=['file'])
+    iotests.main(supported_protocols=['file'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/304 b/tests/qemu-iotests/304
index 198f2820871e..d465a519a932 100755
--- a/tests/qemu-iotests/304
+++ b/tests/qemu-iotests/304
@@ -24,7 +24,8 @@ import iotests
 from iotests import qemu_img_create, qemu_img_log, file_path
 
 iotests.script_initialize(supported_fmts=['qcow2'],
-                          supported_protocols=['file'])
+                          supported_protocols=['file'],
+                          require_hmp=True)
 
 test_img = file_path('test.qcow2')
 target_img = file_path('target.qcow2')
diff --git a/tests/qemu-iotests/310 b/tests/qemu-iotests/310
index 650d2cb6fb3e..7f290898fea0 100755
--- a/tests/qemu-iotests/310
+++ b/tests/qemu-iotests/310
@@ -25,7 +25,8 @@ from iotests import log, qemu_img, qemu_io
 
 # Need backing file support
 iotests.script_initialize(supported_fmts=['qcow2'],
-                          supported_platforms=['linux'])
+                          supported_platforms=['linux'],
+                          require_hmp=True)
 
 log('')
 log('=== Copy-on-read across nodes ===')
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index bcb1ec50a93d..262fe63da820 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -995,6 +995,14 @@ _notrun_on_fuse_error()
     esac
 }
 
+_require_hmp()
+{
+    if echo quit | $QEMU -M none -display none -monitor stdio 2>&1 |
+            grep -q "HMP monitor is not available"; then
+        _notrun "HMP monitor not available"
+    fi
+}
+
 # Check that we have a file system that allows huge (but very sparse) files
 #
 _require_large_file()
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index f36bcf316429..7d5a77a85e58 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -1456,6 +1456,15 @@ def _verify_formats(required_formats: Sequence[str] = ()) -> None:
         notrun(f'formats {usf_list} are not whitelisted')
 
 
+def _verify_hmp() -> None:
+    args = [qemu_prog] + qemu_opts + ['-M', 'none', '-monitor', 'stdio']
+    with subprocess.Popen(args, stdin=subprocess.PIPE,
+                          stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+                          universal_newlines=True) as subp:
+        out, _ = subp.communicate('quit\n')
+    if 'HMP monitor is not available' in out:
+        notrun('HMP monitor not available')
+
 def _verify_virtio_blk() -> None:
     out = qemu_pipe('-M', 'none', '-device', 'help')
     if 'virtio-blk' not in out:
@@ -1694,7 +1703,8 @@ def execute_setup_common(supported_fmts: Sequence[str] = (),
                          supported_protocols: Sequence[str] = (),
                          unsupported_protocols: Sequence[str] = (),
                          required_fmts: Sequence[str] = (),
-                         unsupported_imgopts: Sequence[str] = ()) -> bool:
+                         unsupported_imgopts: Sequence[str] = (),
+                         require_hmp: bool = False) -> bool:
     """
     Perform necessary setup for either script-style or unittest-style tests.
 
@@ -1715,6 +1725,8 @@ def execute_setup_common(supported_fmts: Sequence[str] = (),
     _verify_formats(required_fmts)
     _verify_virtio_blk()
     _verify_imgopts(unsupported_imgopts)
+    if require_hmp:
+        _verify_hmp()
 
     return debug
 
diff --git a/tests/qemu-iotests/tests/backup-discard-source b/tests/qemu-iotests/tests/backup-discard-source
index 6c624bc8b0b0..80ea32c46e3f 100755
--- a/tests/qemu-iotests/tests/backup-discard-source
+++ b/tests/qemu-iotests/tests/backup-discard-source
@@ -160,4 +160,5 @@ class TestBackup(iotests.QMPTestCase):
 
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2'],
-                 supported_protocols=['file'])
+                 supported_protocols=['file'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/tests/copy-before-write b/tests/qemu-iotests/tests/copy-before-write
index 3e43e7127f20..5531ad8a4c0d 100755
--- a/tests/qemu-iotests/tests/copy-before-write
+++ b/tests/qemu-iotests/tests/copy-before-write
@@ -321,4 +321,5 @@ wrote 524288/524288 bytes at offset 524288
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2'],
                  supported_protocols=['file'],
-                 required_fmts=['copy-before-write'])
+                 required_fmts=['copy-before-write'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/tests/image-fleecing b/tests/qemu-iotests/tests/image-fleecing
index 5e3b2c7e46a9..b42aa6967f68 100755
--- a/tests/qemu-iotests/tests/image-fleecing
+++ b/tests/qemu-iotests/tests/image-fleecing
@@ -31,7 +31,8 @@ iotests.script_initialize(
     supported_fmts=['qcow2'],
     supported_platforms=['linux'],
     required_fmts=['copy-before-write'],
-    unsupported_imgopts=['compat']
+    unsupported_imgopts=['compat'],
+    require_hmp=True,
 )
 
 patterns = [('0x5d', '0',         '64k'),
diff --git a/tests/qemu-iotests/tests/iothreads-create b/tests/qemu-iotests/tests/iothreads-create
index 0c862d73f20e..09fe57a09ac0 100755
--- a/tests/qemu-iotests/tests/iothreads-create
+++ b/tests/qemu-iotests/tests/iothreads-create
@@ -22,7 +22,8 @@ import asyncio
 import iotests
 
 iotests.script_initialize(supported_fmts=['qcow2', 'qcow', 'qed', 'vdi',
-                                          'vmdk', 'parallels'])
+                                          'vmdk', 'parallels'],
+                          require_hmp=True)
 iotests.verify_virtio_scsi_pci_or_ccw()
 
 with iotests.FilePath('disk.img') as img_path, \
diff --git a/tests/qemu-iotests/tests/luks-detached-header b/tests/qemu-iotests/tests/luks-detached-header
index 3455fd8de1ef..58eb3c2cc484 100755
--- a/tests/qemu-iotests/tests/luks-detached-header
+++ b/tests/qemu-iotests/tests/luks-detached-header
@@ -313,4 +313,5 @@ class TestDetachedLUKSHeader(QMPTestCase):
 
 if __name__ == "__main__":
     # Test image creation and I/O
-    iotests.main(supported_fmts=["luks"], supported_protocols=["file"])
+    iotests.main(supported_fmts=["luks"], supported_protocols=["file"],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
index 33ff2b861f78..b2b37ada4b27 100755
--- a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
+++ b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
@@ -279,4 +279,5 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase):
 
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2'],
-                 unsupported_imgopts=['compat'])
+                 unsupported_imgopts=['compat'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-test b/tests/qemu-iotests/tests/migrate-bitmaps-test
index 8fb4099201de..7b0e709f9b41 100755
--- a/tests/qemu-iotests/tests/migrate-bitmaps-test
+++ b/tests/qemu-iotests/tests/migrate-bitmaps-test
@@ -296,7 +296,8 @@ def main() -> None:
     iotests.main(
         supported_fmts=['qcow2'],
         supported_protocols=['file'],
-        unsupported_imgopts=['compat']
+        unsupported_imgopts=['compat'],
+        require_hmp=True,
     )
 
 
diff --git a/tests/qemu-iotests/tests/mirror-change-copy-mode b/tests/qemu-iotests/tests/mirror-change-copy-mode
index 51788b85c7ac..c9c345f1397c 100755
--- a/tests/qemu-iotests/tests/mirror-change-copy-mode
+++ b/tests/qemu-iotests/tests/mirror-change-copy-mode
@@ -190,4 +190,5 @@ class TestMirrorChangeCopyMode(iotests.QMPTestCase):
 
 if __name__ == '__main__':
     iotests.main(supported_fmts=['qcow2', 'raw'],
-                 supported_protocols=['file'])
+                 supported_protocols=['file'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/tests/mirror-ready-cancel-error b/tests/qemu-iotests/tests/mirror-ready-cancel-error
index ed2e46447e3e..ffa045af2191 100755
--- a/tests/qemu-iotests/tests/mirror-ready-cancel-error
+++ b/tests/qemu-iotests/tests/mirror-ready-cancel-error
@@ -139,4 +139,5 @@ if __name__ == '__main__':
     # LUKS would require special key-secret handling in add_blockdevs()
     iotests.main(supported_fmts=['generic'],
                  unsupported_fmts=['luks'],
-                 supported_protocols=['file'])
+                 supported_protocols=['file'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/tests/qcow2-internal-snapshots b/tests/qemu-iotests/tests/qcow2-internal-snapshots
index 9f83aa890391..d301f0941b5c 100755
--- a/tests/qemu-iotests/tests/qcow2-internal-snapshots
+++ b/tests/qemu-iotests/tests/qcow2-internal-snapshots
@@ -43,6 +43,7 @@ _supported_proto file
 # Internal snapshots are (currently) impossible with refcount_bits=1,
 # and generally impossible with external data files
 _unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]' data_file
+_require_hmp
 
 IMG_SIZE=64M
 
diff --git a/tests/qemu-iotests/tests/qsd-migrate b/tests/qemu-iotests/tests/qsd-migrate
index a4c6592420c4..d76278b576c2 100755
--- a/tests/qemu-iotests/tests/qsd-migrate
+++ b/tests/qemu-iotests/tests/qsd-migrate
@@ -24,7 +24,8 @@ from iotests import filter_qemu_io, filter_qtest
 
 iotests.script_initialize(supported_fmts=['qcow2', 'qed', 'raw'],
                           supported_protocols=['file'],
-                          supported_platforms=['linux'])
+                          supported_platforms=['linux'],
+                          require_hmp=True)
 
 with iotests.FilePath('disk.img') as path, \
      iotests.FilePath('nbd-src.sock', base_dir=iotests.sock_dir) as nbd_src, \
diff --git a/tests/qemu-iotests/tests/reopen-file b/tests/qemu-iotests/tests/reopen-file
index 5a50794ffc41..f8812320ea8f 100755
--- a/tests/qemu-iotests/tests/reopen-file
+++ b/tests/qemu-iotests/tests/reopen-file
@@ -85,4 +85,5 @@ if __name__ == '__main__':
     # Must support creating images and reopen
     iotests.main(supported_fmts=['qcow', 'qcow2', 'qed', 'raw', 'vdi', 'vhdx',
                                  'vmdk', 'vpc'],
-                 supported_protocols=['file'])
+                 supported_protocols=['file'],
+                 require_hmp=True)
diff --git a/tests/qemu-iotests/tests/write-zeroes-unmap b/tests/qemu-iotests/tests/write-zeroes-unmap
index f90fb8e8d270..506ced647bc1 100755
--- a/tests/qemu-iotests/tests/write-zeroes-unmap
+++ b/tests/qemu-iotests/tests/write-zeroes-unmap
@@ -33,6 +33,7 @@ _supported_fmt raw
 _supported_proto file
 _supported_os Linux
 _require_disk_usage
+_require_hmp
 
 create_test_image() {
     _make_test_img -f $IMGFMT 1m
diff --git a/tests/qtest/drive_del-test.c b/tests/qtest/drive_del-test.c
index 30d9451ddda1..804f56cc58db 100644
--- a/tests/qtest/drive_del-test.c
+++ b/tests/qtest/drive_del-test.c
@@ -167,6 +167,11 @@ static void test_drive_without_dev(void)
 {
     QTestState *qts;
 
+#ifndef CONFIG_HMP
+    g_test_skip("HMP not enabled");
+    return;
+#endif
+
     /* Start with an empty drive */
     qts = qtest_init("-drive if=none,id=drive0 -M none");
 
@@ -187,6 +192,11 @@ static void test_after_failed_device_add(void)
     QDict *response;
     QTestState *qts;
 
+#ifndef CONFIG_HMP
+    g_test_skip("HMP not enabled");
+    return;
+#endif
+
     if (!has_device_builtin("virtio-blk")) {
         g_test_skip("Device virtio-blk is not available");
         return;
@@ -223,6 +233,11 @@ static void test_drive_del_device_del(void)
 {
     QTestState *qts;
 
+#ifndef CONFIG_HMP
+    g_test_skip("HMP not enabled");
+    return;
+#endif
+
     if (!has_device_builtin("virtio-scsi")) {
         g_test_skip("Device virtio-scsi is not available");
         return;
@@ -397,6 +412,11 @@ static void test_drive_add_device_add_and_del(void)
     const char *arch = qtest_get_arch();
     const char *machine_addition = "";
 
+#ifndef CONFIG_HMP
+    g_test_skip("HMP not enabled");
+    return;
+#endif
+
     if (!has_device_builtin("virtio-blk")) {
         g_test_skip("Device virtio-blk is not available");
         return;
@@ -424,6 +444,11 @@ static void test_drive_add_device_add_and_del_q35(void)
 {
     QTestState *qts;
 
+#ifndef CONFIG_HMP
+    g_test_skip("HMP not enabled");
+    return;
+#endif
+
     if (!has_device_builtin("virtio-blk")) {
         g_test_skip("Device virtio-blk is not available");
         return;

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 30/49] monitor: isolate HMP declarations in hmp.h
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (28 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 29/49] tests: skip HMP-dependent tests when HMP is disabled Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 20:21   ` Dr. David Alan Gilbert
  2026-08-16 19:12 ` [PATCH v3 31/49] monitor: change HMPCommand cmd to take MonitorHMP Marc-André Lureau
                   ` (18 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Richard Henderson,
	Paolo Bonzini, Alex Bennée, Laurent Vivier, Amit Shah,
	Michael S. Tsirkin, Brian Cain, Pierrick Bouvier,
	Stefano Stabellini, Anthony PERARD, Edgar E. Iglesias,
	Dr. David Alan Gilbert, Samuel Thibault, Jason Wang,
	Yoshinori Sato, Stefan Hajnoczi, xen-devel

Also rename password & commands with hmp in the name, while at it.
Other functions need larger changes which we will take care of next.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 accel/accel-system.c           |  1 +
 accel/tcg/monitor.c            |  1 +
 chardev/char.c                 |  2 +-
 disas/disas-mon.c              |  1 +
 gdbstub/system.c               |  2 +-
 hw/char/virtio-serial-bus.c    |  1 +
 hw/core/machine-hmp-cmds.c     |  1 -
 hw/core/sysbus.c               |  1 +
 hw/hexagon/hexagon_tlb.c       |  1 +
 hw/misc/auxbus.c               |  1 +
 hw/usb/bus.c                   |  1 +
 hw/usb/host-libusb.c           |  1 +
 hw/xen/xen-bus.c               |  1 +
 include/monitor/hmp.h          | 21 +++++++++++++++++++++
 include/monitor/monitor.h      | 18 ------------------
 monitor/hmp.c                  |  8 ++++----
 monitor/monitor-internal.h     |  1 +
 net/slirp.c                    |  1 +
 stubs/monitor-core.c           |  1 +
 stubs/monitor-internal.c       |  2 +-
 target/rx/disas.c              |  1 +
 tests/unit/test-util-sockets.c |  1 +
 tools/qemu-vnc/stubs.c         |  1 +
 trace/trace-hmp-cmds.c         |  1 -
 ui/ui-hmp-cmds.c               |  4 ++--
 util/error-report.c            |  2 +-
 util/qemu-print.c              |  1 +
 27 files changed, 48 insertions(+), 30 deletions(-)

diff --git a/accel/accel-system.c b/accel/accel-system.c
index 9176665202d2..977804c4048a 100644
--- a/accel/accel-system.c
+++ b/accel/accel-system.c
@@ -28,6 +28,7 @@
 #include "qom/compat-properties.h"
 #include "qapi/qapi-commands-accelerator.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "hw/core/boards.h"
 #include "hw/core/cpu.h"
 #include "accel/accel-ops.h"
diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c
index be5c1950177c..74170ddef708 100644
--- a/accel/tcg/monitor.c
+++ b/accel/tcg/monitor.c
@@ -11,6 +11,7 @@
 #include "qapi/type-helpers.h"
 #include "qapi/qapi-commands-machine.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "system/tcg.h"
 #include "tcg/tcg.h"
 #include "internal-common.h"
diff --git a/chardev/char.c b/chardev/char.c
index c6c8133f5c1d..9da0911e503c 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -24,7 +24,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/cutils.h"
-#include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "monitor/qmp-helpers.h"
 #include "qemu/config-file.h"
 #include "qemu/error-report.h"
diff --git a/disas/disas-mon.c b/disas/disas-mon.c
index 9c693618c277..bc9dec3a7761 100644
--- a/disas/disas-mon.c
+++ b/disas/disas-mon.c
@@ -10,6 +10,7 @@
 #include "system/memory.h"
 #include "hw/core/cpu.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 
 /*
  * Get LENGTH bytes from info's buffer, at target address memaddr.
diff --git a/gdbstub/system.c b/gdbstub/system.c
index 070bc26f416c..8a1cdb11db36 100644
--- a/gdbstub/system.c
+++ b/gdbstub/system.c
@@ -29,7 +29,7 @@
 #include "hw/core/boards.h"
 #include "chardev/char.h"
 #include "chardev/char-fe.h"
-#include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "trace.h"
 #include "internals.h"
 
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index c1973f0248fc..02604740f86a 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -25,6 +25,7 @@
 #include "qemu/module.h"
 #include "migration/qemu-file-types.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "qemu/error-report.h"
 #include "qemu/queue.h"
 #include "hw/core/qdev-properties.h"
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
index 686304bafab5..1c700aad3587 100644
--- a/hw/core/machine-hmp-cmds.c
+++ b/hw/core/machine-hmp-cmds.c
@@ -15,7 +15,6 @@
 
 #include "qemu/osdep.h"
 #include "monitor/hmp.h"
-#include "monitor/monitor.h"
 #include "qapi/error.h"
 #include "qapi/qapi-builtin-visit.h"
 #include "qapi/qapi-commands-accelerator.h"
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 3e1160ee921d..13df7cbafe10 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -21,6 +21,7 @@
 #include "qapi/error.h"
 #include "hw/core/sysbus.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "system/address-spaces.h"
 
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
diff --git a/hw/hexagon/hexagon_tlb.c b/hw/hexagon/hexagon_tlb.c
index b6d4aff389e5..2d878cee736d 100644
--- a/hw/hexagon/hexagon_tlb.c
+++ b/hw/hexagon/hexagon_tlb.c
@@ -12,6 +12,7 @@
 #include "hw/core/resettable.h"
 #include "migration/vmstate.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "qapi/error.h"
 #include "exec/page-protection.h"
 #include "exec/target_page.h"
diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
index 877f34560626..ac2525b90fec 100644
--- a/hw/misc/auxbus.c
+++ b/hw/misc/auxbus.c
@@ -33,6 +33,7 @@
 #include "hw/misc/auxbus.h"
 #include "hw/i2c/i2c.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "qapi/error.h"
 
 #ifndef DEBUG_AUX
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 3b6fbd46ac3f..9b9b2e7c2f8f 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -9,6 +9,7 @@
 #include "system/system.h"
 #include "migration/vmstate.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "trace.h"
 #include "qemu/cutils.h"
 
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index b9f3ad3f66dd..af67d5dfeb10 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -48,6 +48,7 @@
 #include "qapi/error.h"
 #include "migration/vmstate.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index dfad2bc5085f..a563f6066bb4 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -17,6 +17,7 @@
 #include "hw/xen/xen-bus.h"
 #include "hw/xen/xen-bus-helper.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "qapi/error.h"
 #include "qobject/qdict.h"
 #include "system/system.h"
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index 9258a049bffb..166cd4100c63 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -18,6 +18,9 @@
 #include "qapi/qapi-types-common.h"
 #include "monitor/monitor.h"
 
+#define TYPE_MONITOR_HMP "monitor-hmp"
+OBJECT_DECLARE_TYPE(MonitorHMP, MonitorHMPClass, MONITOR_HMP);
+
 #define HMP_STUB(cmd) \
     void hmp_##cmd(Monitor *mon, const QDict *qdict) \
     { \
@@ -30,6 +33,24 @@ struct MonitorDef {
     int64_t (*get_value)(Monitor *mon, const MonitorDef *md, int offset);
 };
 
+void monitor_new_hmp(const char *id, const char *chardev_id,
+                     bool use_readline, Error **errp);
+
+int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
+    G_GNUC_PRINTF(2, 0);
+int monitor_printf(Monitor *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
+void monitor_printc(Monitor *mon, int ch);
+
+void monitor_hmp_read_command(MonitorHMP *hmp, int show_prompt);
+int monitor_hmp_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
+                              void *opaque);
+
+void monitor_register_hmp(const char *name, bool info,
+                          void (*cmd)(Monitor *mon, const QDict *qdict));
+void monitor_register_hmp_info_hrt(const char *name,
+                                   HumanReadableText *(*handler)(Error **errp));
+
+
 CPUArchState *mon_get_cpu_env(Monitor *mon);
 CPUState *mon_get_cpu(Monitor *mon);
 
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 9f048ba103b5..72a8f6ea5b4f 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -10,9 +10,6 @@
 #define TYPE_MONITOR "monitor"
 OBJECT_DECLARE_TYPE(Monitor, MonitorClass, MONITOR);
 
-#define TYPE_MONITOR_HMP "monitor-hmp"
-OBJECT_DECLARE_TYPE(MonitorHMP, MonitorHMPClass, MONITOR_HMP);
-
 #define TYPE_MONITOR_QMP "monitor-qmp"
 OBJECT_DECLARE_TYPE(MonitorQMP, MonitorQMPClass, MONITOR_QMP);
 
@@ -30,8 +27,6 @@ void monitor_init_globals_core(void);
 char *monitor_compat_id(void);
 void monitor_new_qmp(const char *id, const char *chardev_id,
                      bool pretty, Error **errp);
-void monitor_new_hmp(const char *id, const char *chardev_id,
-                     bool use_readline, Error **errp);
 int monitor_new(MonitorOptions *opts, bool allow_hmp, Error **errp);
 int monitor_new_opts(QemuOpts *opts, Error **errp);
 void monitor_cleanup(void);
@@ -43,28 +38,15 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp);
 int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp);
 
 int monitor_puts(Monitor *mon, const char *str);
-int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
-    G_GNUC_PRINTF(2, 0);
-int monitor_printf(Monitor *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
-void monitor_printc(Monitor *mon, int ch);
 void monitor_flush(Monitor *mon);
 int monitor_get_cpu_index(Monitor *mon);
 
 int monitor_puts_locked(Monitor *mon, const char *str);
 void monitor_flush_locked(Monitor *mon);
 
-void monitor_read_command(MonitorHMP *hmp, int show_prompt);
-int monitor_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
-                          void *opaque);
-
 AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id,
                                 const char *opaque, Error **errp);
 int monitor_fdset_dup_fd_add(int64_t fdset_id, int flags, Error **errp);
 void monitor_fdset_dup_fd_remove(int dup_fd);
 
-void monitor_register_hmp(const char *name, bool info,
-                          void (*cmd)(Monitor *mon, const QDict *qdict));
-void monitor_register_hmp_info_hrt(const char *name,
-                                   HumanReadableText *(*handler)(Error **errp));
-
 #endif /* MONITOR_H */
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 8134dfaad4bb..b4d05d47c4bf 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -136,7 +136,7 @@ static void monitor_command_cb(void *opaque, const char *cmdline,
     monitor_resume(&hmp->parent_obj);
 }
 
-void monitor_read_command(MonitorHMP *hmp, int show_prompt)
+void monitor_hmp_read_command(MonitorHMP *hmp, int show_prompt)
 {
     if (!hmp->rs) {
         return;
@@ -148,8 +148,8 @@ void monitor_read_command(MonitorHMP *hmp, int show_prompt)
     }
 }
 
-int monitor_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
-                          void *opaque)
+int monitor_hmp_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
+                              void *opaque)
 {
     if (hmp->rs) {
         readline_start(hmp->rs, "Password: ", 1, readline_func, opaque);
@@ -1647,7 +1647,7 @@ static void monitor_hmp_complete(UserCreatable *uc, Error **errp)
                                     monitor_readline_flush,
                                     hmp,
                                     monitor_find_completion);
-            monitor_read_command(hmp, 0);
+            monitor_hmp_read_command(hmp, 0);
         }
 
         qemu_chr_fe_set_handlers(&hmp->parent_obj.chr,
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index fdeeeb853636..ee9ba0c8231e 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -27,6 +27,7 @@
 
 #include "chardev/char-fe.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "qapi/qapi-emit-events.h"
 #include "qapi/qapi-types-control.h"
 #include "qapi/qapi-types-qom.h"
diff --git a/net/slirp.c b/net/slirp.c
index 517dd23be14b..9bf09a2c8bc9 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -36,6 +36,7 @@
 #include "clients.h"
 #include "hub.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "qemu/error-report.h"
 #include "qemu/sockets.h"
 #include <libslirp.h>
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
index a7c32297c90a..b0c7002bd406 100644
--- a/stubs/monitor-core.c
+++ b/stubs/monitor-core.c
@@ -1,5 +1,6 @@
 #include "qemu/osdep.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "qapi/qapi-emit-events.h"
 
 Monitor *monitor_cur(void)
diff --git a/stubs/monitor-internal.c b/stubs/monitor-internal.c
index 731fad221ecc..6f69f1f14ae4 100644
--- a/stubs/monitor-internal.c
+++ b/stubs/monitor-internal.c
@@ -1,6 +1,6 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
-#include "monitor/monitor.h"
+#include "monitor/hmp.h"
 
 int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
 {
diff --git a/target/rx/disas.c b/target/rx/disas.c
index 67b932882914..0eb2ee6f4507 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -19,6 +19,7 @@
 #include "qemu/osdep.h"
 #include "disas/dis-asm.h"
 #include "qemu/bitops.h"
+#include "monitor/hmp.h"
 #include "cpu.h"
 
 typedef struct DisasContext {
diff --git a/tests/unit/test-util-sockets.c b/tests/unit/test-util-sockets.c
index ab3f39c3efb5..b2a884529598 100644
--- a/tests/unit/test-util-sockets.c
+++ b/tests/unit/test-util-sockets.c
@@ -24,6 +24,7 @@
 #include "qapi/error.h"
 #include "socket-helpers.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 
 static void test_fd_is_socket_bad(void)
 {
diff --git a/tools/qemu-vnc/stubs.c b/tools/qemu-vnc/stubs.c
index 1c82d8cff430..26597fefaa99 100644
--- a/tools/qemu-vnc/stubs.c
+++ b/tools/qemu-vnc/stubs.c
@@ -9,6 +9,7 @@
 #include "system/runstate.h"
 #include "hw/core/qdev.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "migration/vmstate.h"
 
 bool runstate_is_running(void)
diff --git a/trace/trace-hmp-cmds.c b/trace/trace-hmp-cmds.c
index 390173095cff..c8f0133abecf 100644
--- a/trace/trace-hmp-cmds.c
+++ b/trace/trace-hmp-cmds.c
@@ -25,7 +25,6 @@
 #include "qemu/osdep.h"
 #include "monitor/hmp.h"
 #include "monitor/hmp-completion.h"
-#include "monitor/monitor.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-trace.h"
 #include "qobject/qdict.h"
diff --git a/ui/ui-hmp-cmds.c b/ui/ui-hmp-cmds.c
index 806a7bece7cb..4ef459490ba2 100644
--- a/ui/ui-hmp-cmds.c
+++ b/ui/ui-hmp-cmds.c
@@ -327,7 +327,7 @@ static void hmp_change_read_arg(void *opaque, const char *password,
                                 void *readline_opaque)
 {
     qmp_change_vnc_password(password, NULL);
-    monitor_read_command(opaque, 1);
+    monitor_hmp_read_command(opaque, 1);
 }
 
 void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
@@ -344,7 +344,7 @@ void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
     }
     if (!arg) {
         MonitorHMP *hmp = MONITOR_HMP(mon);
-        monitor_read_password(hmp, hmp_change_read_arg, NULL);
+        monitor_hmp_read_password(hmp, hmp_change_read_arg, NULL);
     } else {
         qmp_change_vnc_password(arg, errp);
     }
diff --git a/util/error-report.c b/util/error-report.c
index f333af9249b9..aaa15bc79827 100644
--- a/util/error-report.c
+++ b/util/error-report.c
@@ -11,7 +11,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "qemu/error-report.h"
 
 /*
diff --git a/util/qemu-print.c b/util/qemu-print.c
index 7b9591035e57..a2d1f0244168 100644
--- a/util/qemu-print.c
+++ b/util/qemu-print.c
@@ -12,6 +12,7 @@
 
 #include "qemu/osdep.h"
 #include "monitor/monitor.h"
+#include "monitor/hmp.h"
 #include "qemu/qemu-print.h"
 
 /*

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 31/49] monitor: change HMPCommand cmd to take MonitorHMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (29 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 30/49] monitor: isolate HMP declarations in hmp.h Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-16 21:51   ` Dr. David Alan Gilbert
  2026-08-16 19:12 ` [PATCH v3 32/49] monitor: make hmp_handle_error() " Marc-André Lureau
                   ` (17 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Gerd Hoffmann,
	Gonglei (Arei), zhenwei pi, Kevin Wolf, Hanna Reitz,
	Paolo Bonzini, Ani Sinha, David Woodhouse, Paul Durrant,
	Michael S. Tsirkin, Richard Henderson, Marcelo Tosatti,
	Mark Cave-Ayland, Jiri Pirko, Jason Wang, Halil Pasic,
	Christian Borntraeger, Jason Herne, Ilya Leoshkevich,
	David Hildenbrand, Eric Farman, Matthew Rosato, Cornelia Huck,
	Dr. David Alan Gilbert, Samuel Thibault, Hyman Huang, Peter Xu,
	Fabiano Rosas, Alex Bennée, Stefan Berger, Zhao Liu,
	Laurent Vivier, Nicholas Piggin, Chinmay Rath, Glenn Miles,
	Harsh Prateek Bora, Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Yoshinori Sato,
	Artyom Tarasenko, Max Filippov, Stefan Hajnoczi, qemu-block, kvm,
	qemu-ppc, qemu-s390x, qemu-riscv

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.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 audio/audio-hmp-cmds.c          |   8 +-
 backends/cryptodev-hmp-cmds.c   |   3 +-
 block/monitor/block-hmp-cmds.c  |  78 +++++++----
 chardev/char-hmp-cmds.c         |  21 ++-
 dump/dump-hmp-cmds.c            |   6 +-
 hw/core/machine-hmp-cmds.c      |  49 ++++---
 hw/i386/kvm/xen-stubs.c         |   6 +-
 hw/i386/kvm/xen_evtchn.c        |   6 +-
 hw/i386/sgx-hmp-stub.c          |   3 +-
 hw/i386/sgx.c                   |   3 +-
 hw/misc/mos6522-stub.c          |   3 +-
 hw/misc/mos6522.c               |   3 +-
 hw/net/rocker/rocker-hmp-cmds.c |  12 +-
 hw/pci/pci-hmp-cmds.c           |   6 +-
 hw/pci/pci-stub.c               |   5 +-
 hw/s390x/s390-skeys.c           |   5 +-
 hw/s390x/s390-stattrib.c        |   6 +-
 hw/uefi/ovmf-log.c              |   3 +-
 hw/usb/host-libusb.c            |   3 +-
 hw/virtio/virtio-hmp-cmds.c     |  15 +-
 include/block/block-hmp-cmds.h  |  55 ++++----
 include/hw/usb/usb.h            |   3 +-
 include/monitor/hmp.h           | 294 ++++++++++++++++++++--------------------
 include/monitor/qdev.h          |   5 +-
 include/net/net.h               |   5 +-
 include/net/slirp.h             |   8 +-
 migration/dirtyrate.c           |   6 +-
 migration/migration-hmp-cmds.c  |  48 ++++---
 monitor/hmp-cmds.c              |  96 ++++++++-----
 monitor/hmp.c                   |  17 ++-
 monitor/monitor-internal.h      |   2 +-
 net/net-hmp-cmds.c              |  14 +-
 net/slirp.c                     |   9 +-
 qom/qom-hmp-cmds.c              |  18 ++-
 replay/replay-debugging.c       |   9 +-
 replay/stubs-system.c           |   8 +-
 stats/stats-hmp-cmds.c          |   3 +-
 stubs/hmp-cmd-info_sev.c        |   3 +-
 system/dirtylimit-hmp-cmds.c    |   9 +-
 system/qdev-monitor.c           |  11 +-
 system/runstate-hmp-cmds.c      |   9 +-
 system/tpm-hmp-cmds.c           |   3 +-
 target/i386/cpu-apic.c          |   3 +-
 target/i386/monitor.c           |   9 +-
 target/i386/sev.c               |   3 +-
 target/m68k/monitor.c           |   3 +-
 target/ppc/monitor.c            |   3 +-
 target/riscv/monitor.c          |   3 +-
 target/sh4/monitor.c            |   3 +-
 target/sparc/monitor.c          |   3 +-
 target/xtensa/monitor.c         |   3 +-
 trace/trace-hmp-cmds.c          |   8 +-
 ui/ui-hmp-cmds.c                |  31 +++--
 53 files changed, 561 insertions(+), 390 deletions(-)

diff --git a/audio/audio-hmp-cmds.c b/audio/audio-hmp-cmds.c
index 1ffb5ebc7420..4d326ec99fdf 100644
--- a/audio/audio-hmp-cmds.c
+++ b/audio/audio-hmp-cmds.c
@@ -32,8 +32,9 @@
 
 static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
 
-void hmp_info_capture(Monitor *mon, const QDict *qdict)
+void hmp_info_capture(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     int i;
     CaptureState *s;
 
@@ -45,7 +46,7 @@ void hmp_info_capture(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_stopcapture(Monitor *mon, const QDict *qdict)
+void hmp_stopcapture(MonitorHMP *hmp, const QDict *qdict)
 {
     int i;
     int n = qdict_get_int(qdict, "n");
@@ -63,8 +64,9 @@ void hmp_stopcapture(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_wavcapture(Monitor *mon, const QDict *qdict)
+void hmp_wavcapture(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *path = qdict_get_str(qdict, "path");
     int freq = qdict_get_try_int(qdict, "freq", 44100);
     int bits = qdict_get_try_int(qdict, "bits", 16);
diff --git a/backends/cryptodev-hmp-cmds.c b/backends/cryptodev-hmp-cmds.c
index 01396d227c88..fb62428d795a 100644
--- a/backends/cryptodev-hmp-cmds.c
+++ b/backends/cryptodev-hmp-cmds.c
@@ -17,8 +17,9 @@
 #include "qobject/qdict.h"
 
 
-void hmp_info_cryptodev(Monitor *mon, const QDict *qdict)
+void hmp_info_cryptodev(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     QCryptodevInfoList *il;
     QCryptodevBackendServiceTypeList *sl;
     QCryptodevBackendClientList *cl;
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index 22fa03089ea3..3914b5189d56 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -87,8 +87,9 @@ out:
     hmp_handle_error(mon, err);
 }
 
-void hmp_drive_add(Monitor *mon, const QDict *qdict)
+void hmp_drive_add(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     DriveInfo *dinfo;
     QemuOpts *opts;
@@ -135,8 +136,9 @@ err:
     hmp_handle_error(mon, err);
 }
 
-void hmp_drive_del(Monitor *mon, const QDict *qdict)
+void hmp_drive_del(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *id = qdict_get_str(qdict, "id");
     BlockBackend *blk;
     BlockDriverState *bs;
@@ -194,8 +196,9 @@ unlock:
     hmp_handle_error(mon, err);
 }
 
-void hmp_commit(Monitor *mon, const QDict *qdict)
+void hmp_commit(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     BlockBackend *blk;
     int ret;
@@ -232,8 +235,9 @@ end:
     hmp_handle_error(mon, err);
 }
 
-void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
+void hmp_drive_mirror(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *filename = qdict_get_str(qdict, "target");
     const char *format = qdict_get_try_str(qdict, "format");
     bool reuse = qdict_get_try_bool(qdict, "reuse", false);
@@ -258,8 +262,9 @@ end:
     hmp_handle_error(mon, err);
 }
 
-void hmp_drive_backup(Monitor *mon, const QDict *qdict)
+void hmp_drive_backup(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     const char *filename = qdict_get_str(qdict, "target");
     const char *format = qdict_get_try_str(qdict, "format");
@@ -288,8 +293,9 @@ end:
     hmp_handle_error(mon, err);
 }
 
-void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
+void hmp_block_job_set_speed(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
     int64_t value = qdict_get_int(qdict, "speed");
@@ -299,8 +305,9 @@ void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, error);
 }
 
-void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
+void hmp_block_job_cancel(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
     bool force = qdict_get_try_bool(qdict, "force", false);
@@ -310,8 +317,9 @@ void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, error);
 }
 
-void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
+void hmp_block_job_pause(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
 
@@ -320,8 +328,9 @@ void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, error);
 }
 
-void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
+void hmp_block_job_resume(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
 
@@ -330,8 +339,9 @@ void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, error);
 }
 
-void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
+void hmp_block_job_complete(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
 
@@ -340,8 +350,9 @@ void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, error);
 }
 
-void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
+void hmp_snapshot_blkdev(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     const char *filename = qdict_get_str(qdict, "snapshot-file");
     const char *format = qdict_get_try_str(qdict, "format");
@@ -355,8 +366,9 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
+void hmp_snapshot_blkdev_internal(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     const char *name = qdict_get_str(qdict, "name");
     Error *err = NULL;
@@ -365,8 +377,9 @@ void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
+void hmp_snapshot_delete_blkdev_internal(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     const char *name = qdict_get_str(qdict, "name");
     const char *id = qdict_get_try_str(qdict, "id");
@@ -376,8 +389,9 @@ void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
+void hmp_nbd_server_start(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *uri = qdict_get_str(qdict, "uri");
     bool writable = qdict_get_try_bool(qdict, "writable", false);
     bool all = qdict_get_try_bool(qdict, "all", false);
@@ -438,8 +452,9 @@ exit:
     hmp_handle_error(mon, local_err);
 }
 
-void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
+void hmp_nbd_server_add(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     const char *name = qdict_get_try_str(qdict, "name");
     bool writable = qdict_get_try_bool(qdict, "writable", false);
@@ -456,8 +471,9 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, local_err);
 }
 
-void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict)
+void hmp_nbd_server_remove(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *name = qdict_get_str(qdict, "name");
     bool force = qdict_get_try_bool(qdict, "force", false);
     Error *err = NULL;
@@ -467,16 +483,18 @@ void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
+void hmp_nbd_server_stop(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_nbd_server_stop(&err);
     hmp_handle_error(mon, err);
 }
 
-void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict)
+void coroutine_fn hmp_block_resize(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     int64_t size = qdict_get_int(qdict, "size");
     Error *err = NULL;
@@ -485,8 +503,9 @@ void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_block_stream(Monitor *mon, const QDict *qdict)
+void hmp_block_stream(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
     const char *base = qdict_get_try_str(qdict, "base");
@@ -500,8 +519,9 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, error);
 }
 
-void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
+void hmp_block_set_io_throttle(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     char *device = (char *) qdict_get_str(qdict, "device");
     BlockIOThrottle throttle = {
@@ -528,8 +548,9 @@ void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_eject(Monitor *mon, const QDict *qdict)
+void hmp_eject(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     bool force = qdict_get_try_bool(qdict, "force", false);
     const char *device = qdict_get_str(qdict, "device");
     Error *err = NULL;
@@ -538,8 +559,9 @@ void hmp_eject(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_qemu_io(Monitor *mon, const QDict *qdict)
+void hmp_qemu_io(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     bool qdev = qdict_get_try_bool(qdict, "qdev", false);
     const char *device = qdict_get_str(qdict, "device");
     const char *command = qdict_get_str(qdict, "command");
@@ -666,8 +688,9 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
     }
 }
 
-void hmp_info_block(Monitor *mon, const QDict *qdict)
+void hmp_info_block(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     BlockInfoList *block_list, *info;
     BlockDeviceInfoList *blockdev_list, *blockdev;
     const char *device = qdict_get_try_str(qdict, "device");
@@ -719,8 +742,9 @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
     qapi_free_BlockDeviceInfoList(blockdev_list);
 }
 
-void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
+void hmp_info_blockstats(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     BlockStatsList *stats_list, *stats;
 
     stats_list = qmp_query_blockstats(false, false, NULL);
@@ -757,8 +781,9 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
     qapi_free_BlockStatsList(stats_list);
 }
 
-void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
+void hmp_info_block_jobs(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     BlockJobInfoList *list;
 
     list = qmp_query_block_jobs(&error_abort);
@@ -793,8 +818,9 @@ void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
     qapi_free_BlockJobInfoList(list);
 }
 
-void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
+void hmp_info_snapshots(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     BlockDriverState *bs, *bs1;
     BdrvNextIterator it1;
     QEMUSnapshotInfo *sn_tab, *sn;
diff --git a/chardev/char-hmp-cmds.c b/chardev/char-hmp-cmds.c
index f377e00b6991..d4a5a3a255a5 100644
--- a/chardev/char-hmp-cmds.c
+++ b/chardev/char-hmp-cmds.c
@@ -24,8 +24,9 @@
 #include "qemu/config-file.h"
 #include "qemu/option.h"
 
-void hmp_info_chardev(Monitor *mon, const QDict *qdict)
+void hmp_info_chardev(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     ChardevInfoList *char_info, *info;
 
     char_info = qmp_query_chardev(NULL);
@@ -37,8 +38,9 @@ void hmp_info_chardev(Monitor *mon, const QDict *qdict)
     qapi_free_ChardevInfoList(char_info);
 }
 
-void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
+void hmp_ringbuf_write(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *chardev = qdict_get_str(qdict, "device");
     const char *data = qdict_get_str(qdict, "data");
     Error *err = NULL;
@@ -48,8 +50,9 @@ void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
+void hmp_ringbuf_read(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     uint32_t size = qdict_get_int(qdict, "size");
     const char *chardev = qdict_get_str(qdict, "device");
     char *data;
@@ -77,8 +80,9 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
     g_free(data);
 }
 
-void hmp_chardev_add(Monitor *mon, const QDict *qdict)
+void hmp_chardev_add(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *args = qdict_get_str(qdict, "args");
     Error *err = NULL;
     QemuOpts *opts;
@@ -93,8 +97,9 @@ void hmp_chardev_add(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_chardev_change(Monitor *mon, const QDict *qdict)
+void hmp_chardev_change(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *args = qdict_get_str(qdict, "args");
     const char *id;
     Error *err = NULL;
@@ -127,16 +132,18 @@ end:
     hmp_handle_error(mon, err);
 }
 
-void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
+void hmp_chardev_remove(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *local_err = NULL;
 
     qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
     hmp_handle_error(mon, local_err);
 }
 
-void hmp_chardev_send_break(Monitor *mon, const QDict *qdict)
+void hmp_chardev_send_break(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *local_err = NULL;
 
     qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err);
diff --git a/dump/dump-hmp-cmds.c b/dump/dump-hmp-cmds.c
index 21023db6fd85..ba78ad026f1e 100644
--- a/dump/dump-hmp-cmds.c
+++ b/dump/dump-hmp-cmds.c
@@ -12,8 +12,9 @@
 #include "qapi/qapi-commands-dump.h"
 #include "qobject/qdict.h"
 
-void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
+void hmp_dump_guest_memory(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     bool win_dmp = qdict_get_try_bool(qdict, "windmp", false);
     bool paging = qdict_get_try_bool(qdict, "paging", false);
@@ -83,8 +84,9 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
     g_free(prot);
 }
 
-void hmp_info_dump(Monitor *mon, const QDict *qdict)
+void hmp_info_dump(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     DumpQueryResult *result = qmp_query_dump(NULL);
 
     assert(result && result->status < DUMP_STATUS__MAX);
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
index 1c700aad3587..48fa27f12705 100644
--- a/hw/core/machine-hmp-cmds.c
+++ b/hw/core/machine-hmp-cmds.c
@@ -25,8 +25,9 @@
 #include "system/numa.h"
 #include "hw/core/boards.h"
 
-void hmp_info_cpus(Monitor *mon, const QDict *qdict)
+void hmp_info_cpus(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     CpuInfoFastList *cpu_list, *cpu;
 
     cpu_list = qmp_query_cpus_fast(NULL);
@@ -48,8 +49,9 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict)
     qapi_free_CpuInfoFastList(cpu_list);
 }
 
-void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
+void hmp_hotpluggable_cpus(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     HotpluggableCPUList *l = qmp_query_hotpluggable_cpus(&err);
     HotpluggableCPUList *saved = l;
@@ -106,8 +108,9 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
     qapi_free_HotpluggableCPUList(saved);
 }
 
-void hmp_info_memdev(Monitor *mon, const QDict *qdict)
+void hmp_info_memdev(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     MemdevList *memdev_list = qmp_query_memdev(&err);
     MemdevList *m = memdev_list;
@@ -147,8 +150,9 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_info_kvm(Monitor *mon, const QDict *qdict)
+void hmp_info_kvm(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     KvmInfo *info;
 
     info = qmp_query_kvm(NULL);
@@ -162,8 +166,9 @@ void hmp_info_kvm(Monitor *mon, const QDict *qdict)
     qapi_free_KvmInfo(info);
 }
 
-void hmp_info_accelerators(Monitor *mon, const QDict *qdict)
+void hmp_info_accelerators(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     AcceleratorInfo *info;
     AcceleratorList *accel;
 
@@ -180,8 +185,9 @@ void hmp_info_accelerators(Monitor *mon, const QDict *qdict)
     qapi_free_AcceleratorInfo(info);
 }
 
-void hmp_info_uuid(Monitor *mon, const QDict *qdict)
+void hmp_info_uuid(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     UuidInfo *info;
 
     info = qmp_query_uuid(NULL);
@@ -189,8 +195,9 @@ void hmp_info_uuid(Monitor *mon, const QDict *qdict)
     qapi_free_UuidInfo(info);
 }
 
-void hmp_info_balloon(Monitor *mon, const QDict *qdict)
+void hmp_info_balloon(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     BalloonInfo *info;
     Error *err = NULL;
 
@@ -204,18 +211,19 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
     qapi_free_BalloonInfo(info);
 }
 
-void hmp_system_reset(Monitor *mon, const QDict *qdict)
+void hmp_system_reset(MonitorHMP *hmp, const QDict *qdict)
 {
     qmp_system_reset(NULL);
 }
 
-void hmp_system_powerdown(Monitor *mon, const QDict *qdict)
+void hmp_system_powerdown(MonitorHMP *hmp, const QDict *qdict)
 {
     qmp_system_powerdown(NULL);
 }
 
-void hmp_memsave(Monitor *mon, const QDict *qdict)
+void hmp_memsave(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     uint32_t size = qdict_get_int(qdict, "size");
     const char *filename = qdict_get_str(qdict, "filename");
     uint64_t addr = qdict_get_int(qdict, "val");
@@ -231,8 +239,9 @@ void hmp_memsave(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_pmemsave(Monitor *mon, const QDict *qdict)
+void hmp_pmemsave(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     uint32_t size = qdict_get_int(qdict, "size");
     const char *filename = qdict_get_str(qdict, "filename");
     uint64_t addr = qdict_get_int(qdict, "val");
@@ -242,24 +251,27 @@ void hmp_pmemsave(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
+void hmp_system_wakeup(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_system_wakeup(&err);
     hmp_handle_error(mon, err);
 }
 
-void hmp_nmi(Monitor *mon, const QDict *qdict)
+void hmp_nmi(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_inject_nmi(&err);
     hmp_handle_error(mon, err);
 }
 
-void hmp_balloon(Monitor *mon, const QDict *qdict)
+void hmp_balloon(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     int64_t value = qdict_get_int(qdict, "value");
     Error *err = NULL;
 
@@ -267,8 +279,9 @@ void hmp_balloon(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
+void hmp_info_memory_devices(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err);
     MemoryDeviceInfoList *info;
@@ -370,8 +383,9 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict)
+void hmp_info_vm_generation_id(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     GuidInfo *info = qmp_query_vm_generation_id(&err);
     if (info) {
@@ -381,8 +395,9 @@ void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict)
     qapi_free_GuidInfo(info);
 }
 
-void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict)
+void hmp_info_memory_size_summary(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     MemoryInfo *info = qmp_query_memory_size_summary(&err);
     if (info) {
diff --git a/hw/i386/kvm/xen-stubs.c b/hw/i386/kvm/xen-stubs.c
index bf6ac28bef47..ab1eb14f99e0 100644
--- a/hw/i386/kvm/xen-stubs.c
+++ b/hw/i386/kvm/xen-stubs.c
@@ -40,12 +40,14 @@ void xen_primary_console_set_be_port(uint16_t port)
 {
 }
 
-void hmp_xen_event_list(Monitor *mon, const QDict *qdict)
+void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     monitor_printf(mon, "XEN emulation is not available in this QEMU\n");
 }
 
-void hmp_xen_event_inject(Monitor *mon, const QDict *qdict)
+void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     monitor_printf(mon, "XEN emulation is not available in this QEMU\n");
 }
diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c
index 8b243984e412..845838c372d5 100644
--- a/hw/i386/kvm/xen_evtchn.c
+++ b/hw/i386/kvm/xen_evtchn.c
@@ -2344,8 +2344,9 @@ void qmp_xen_event_inject(uint32_t port, Error **errp)
     }
 }
 
-void hmp_xen_event_list(Monitor *mon, const QDict *qdict)
+void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     EvtchnInfoList *iter, *info_list;
     Error *err = NULL;
 
@@ -2379,8 +2380,9 @@ void hmp_xen_event_list(Monitor *mon, const QDict *qdict)
     qapi_free_EvtchnInfoList(info_list);
 }
 
-void hmp_xen_event_inject(Monitor *mon, const QDict *qdict)
+void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     int port = qdict_get_int(qdict, "port");
     Error *err = NULL;
 
diff --git a/hw/i386/sgx-hmp-stub.c b/hw/i386/sgx-hmp-stub.c
index cf1d9a6344b0..a4848ae1d1a7 100644
--- a/hw/i386/sgx-hmp-stub.c
+++ b/hw/i386/sgx-hmp-stub.c
@@ -10,7 +10,8 @@
 #include "monitor/hmp.h"
 #include "monitor/monitor.h"
 
-void hmp_info_sgx(Monitor *mon, const QDict *qdict)
+void hmp_info_sgx(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     monitor_printf(mon, "SGX is not available in this QEMU\n");
 }
diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
index 7e4c509f5a4a..77b41d234c9f 100644
--- a/hw/i386/sgx.c
+++ b/hw/i386/sgx.c
@@ -234,8 +234,9 @@ SgxInfo *qmp_query_sgx(Error **errp)
     return info;
 }
 
-void hmp_info_sgx(Monitor *mon, const QDict *qdict)
+void hmp_info_sgx(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     SgxEpcSectionList *section_list, *section;
     g_autoptr(SgxInfo) info = qmp_query_sgx(&err);
diff --git a/hw/misc/mos6522-stub.c b/hw/misc/mos6522-stub.c
index 85eb0ee36ee1..6a7d76292f00 100644
--- a/hw/misc/mos6522-stub.c
+++ b/hw/misc/mos6522-stub.c
@@ -10,7 +10,8 @@
 #include "monitor/monitor.h"
 #include "monitor/hmp.h"
 
-void hmp_info_via(Monitor *mon, const QDict *qdict)
+void hmp_info_via(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     monitor_printf(mon, "MOS6522 VIA is not available in this QEMU\n");
 }
diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index bae766ef1782..15a6a1a75745 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -586,8 +586,9 @@ static HumanReadableText *qmp_x_query_via(Error **errp)
     return human_readable_text_from_str(buf);
 }
 
-void hmp_info_via(Monitor *mon, const QDict *qdict)
+void hmp_info_via(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     g_autoptr(HumanReadableText) info = qmp_x_query_via(&err);
 
diff --git a/hw/net/rocker/rocker-hmp-cmds.c b/hw/net/rocker/rocker-hmp-cmds.c
index df40991f6d20..856aaef5e210 100644
--- a/hw/net/rocker/rocker-hmp-cmds.c
+++ b/hw/net/rocker/rocker-hmp-cmds.c
@@ -20,8 +20,9 @@
 #include "qapi/qapi-commands-rocker.h"
 #include "qobject/qdict.h"
 
-void hmp_rocker(Monitor *mon, const QDict *qdict)
+void hmp_rocker(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *name = qdict_get_str(qdict, "name");
     RockerSwitch *rocker;
     Error *err = NULL;
@@ -38,8 +39,9 @@ void hmp_rocker(Monitor *mon, const QDict *qdict)
     qapi_free_RockerSwitch(rocker);
 }
 
-void hmp_rocker_ports(Monitor *mon, const QDict *qdict)
+void hmp_rocker_ports(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     RockerPortList *list, *port;
     const char *name = qdict_get_str(qdict, "name");
     Error *err = NULL;
@@ -65,8 +67,9 @@ void hmp_rocker_ports(Monitor *mon, const QDict *qdict)
     qapi_free_RockerPortList(list);
 }
 
-void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict)
+void hmp_rocker_of_dpa_flows(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     RockerOfDpaFlowList *list, *info;
     const char *name = qdict_get_str(qdict, "name");
     uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1);
@@ -214,8 +217,9 @@ void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict)
     qapi_free_RockerOfDpaFlowList(list);
 }
 
-void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
+void hmp_rocker_of_dpa_groups(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     RockerOfDpaGroupList *list, *g;
     const char *name = qdict_get_str(qdict, "name");
     uint8_t type = qdict_get_try_int(qdict, "type", 9);
diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c
index a5f6483cc3d2..be24aecc8ac8 100644
--- a/hw/pci/pci-hmp-cmds.c
+++ b/hw/pci/pci-hmp-cmds.c
@@ -117,8 +117,9 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
     }
 }
 
-void hmp_info_pci(Monitor *mon, const QDict *qdict)
+void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     PciInfoList *info_list, *info;
 
     info_list = qmp_query_pci(&error_abort);
@@ -170,8 +171,9 @@ void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
     }
 }
 
-void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict)
+void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *id = qdict_get_str(qdict, "id");
     const char *error_name;
diff --git a/hw/pci/pci-stub.c b/hw/pci/pci-stub.c
index 3397d0c82ea8..a80e34175462 100644
--- a/hw/pci/pci-stub.c
+++ b/hw/pci/pci-stub.c
@@ -34,12 +34,13 @@ PciInfoList *qmp_query_pci(Error **errp)
     return NULL;
 }
 
-void hmp_info_pci(Monitor *mon, const QDict *qdict)
+void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict)
 {
 }
 
-void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict)
+void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     monitor_printf(mon, "PCI devices not supported\n");
 }
 
diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
index 7dca67d6618c..d8afaf730639 100644
--- a/hw/s390x/s390-skeys.c
+++ b/hw/s390x/s390-skeys.c
@@ -104,8 +104,9 @@ static void write_keys(FILE *f, uint8_t *keys, uint64_t startgfn,
     }
 }
 
-void hmp_info_skeys(Monitor *mon, const QDict *qdict)
+void hmp_info_skeys(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     S390SKeysState *ss = s390_get_skeys_device();
     S390SKeysClass *skeyclass = S390_SKEYS_GET_CLASS(ss);
     uint64_t addr = qdict_get_int(qdict, "addr");
@@ -134,7 +135,7 @@ void hmp_info_skeys(Monitor *mon, const QDict *qdict)
     monitor_printf(mon, "  key: 0x%X\n", key);
 }
 
-void hmp_dump_skeys(Monitor *mon, const QDict *qdict)
+void hmp_dump_skeys(MonitorHMP *hmp, const QDict *qdict)
 {
     const char *filename = qdict_get_str(qdict, "filename");
     Error *err = NULL;
diff --git a/hw/s390x/s390-stattrib.c b/hw/s390x/s390-stattrib.c
index b0f04eb30c7f..b4a405455901 100644
--- a/hw/s390x/s390-stattrib.c
+++ b/hw/s390x/s390-stattrib.c
@@ -59,8 +59,9 @@ void s390_stattrib_init(void)
 
 /* Console commands: */
 
-void hmp_migrationmode(Monitor *mon, const QDict *qdict)
+void hmp_migrationmode(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     S390StAttribState *sas = s390_get_stattrib_device();
     S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
     uint64_t what = qdict_get_int(qdict, "mode");
@@ -74,8 +75,9 @@ void hmp_migrationmode(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_info_cmma(Monitor *mon, const QDict *qdict)
+void hmp_info_cmma(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     S390StAttribState *sas = s390_get_stattrib_device();
     S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
     uint64_t addr = qdict_get_int(qdict, "addr");
diff --git a/hw/uefi/ovmf-log.c b/hw/uefi/ovmf-log.c
index 3a24afd9417d..c97622b2aad6 100644
--- a/hw/uefi/ovmf-log.c
+++ b/hw/uefi/ovmf-log.c
@@ -256,8 +256,9 @@ FirmwareLog *qmp_query_firmware_log(bool have_max_size, uint64_t max_size,
     return ret;
 }
 
-void hmp_info_firmware_log(Monitor *mon, const QDict *qdict)
+void hmp_info_firmware_log(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     g_autofree gchar *log_esc = NULL;
     g_autofree guchar *log_out = NULL;
     Error *err = NULL;
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index af67d5dfeb10..c02343d3a655 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1920,8 +1920,9 @@ static void usb_host_auto_check(void *unused)
     timer_mod(usb_auto_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 2000);
 }
 
-void hmp_info_usbhost(Monitor *mon, const QDict *qdict)
+void hmp_info_usbhost(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     libusb_device **devs = NULL;
     struct libusb_device_descriptor ddesc;
     char port[16];
diff --git a/hw/virtio/virtio-hmp-cmds.c b/hw/virtio/virtio-hmp-cmds.c
index a91bb7dbeda5..49f3367785ba 100644
--- a/hw/virtio/virtio-hmp-cmds.c
+++ b/hw/virtio/virtio-hmp-cmds.c
@@ -80,8 +80,9 @@ static void hmp_virtio_dump_features(Monitor *mon,
     }
 }
 
-void hmp_virtio_query(Monitor *mon, const QDict *qdict)
+void hmp_virtio_query(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     VirtioInfoList *list = qmp_x_query_virtio(&err);
     VirtioInfoList *node;
@@ -105,8 +106,9 @@ void hmp_virtio_query(Monitor *mon, const QDict *qdict)
     qapi_free_VirtioInfoList(list);
 }
 
-void hmp_virtio_status(Monitor *mon, const QDict *qdict)
+void hmp_virtio_status(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *path = qdict_get_try_str(qdict, "path");
     VirtioStatus *s = qmp_x_query_virtio_status(path, &err);
@@ -183,8 +185,9 @@ void hmp_virtio_status(Monitor *mon, const QDict *qdict)
     qapi_free_VirtioStatus(s);
 }
 
-void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict)
+void hmp_vhost_queue_status(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *path = qdict_get_try_str(qdict, "path");
     int queue = qdict_get_int(qdict, "queue");
@@ -216,8 +219,9 @@ void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict)
     qapi_free_VirtVhostQueueStatus(s);
 }
 
-void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict)
+void hmp_virtio_queue_status(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *path = qdict_get_try_str(qdict, "path");
     int queue = qdict_get_int(qdict, "queue");
@@ -261,8 +265,9 @@ void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict)
     qapi_free_VirtQueueStatus(s);
 }
 
-void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict)
+void hmp_virtio_queue_element(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *path = qdict_get_try_str(qdict, "path");
     int queue = qdict_get_int(qdict, "queue");
diff --git a/include/block/block-hmp-cmds.h b/include/block/block-hmp-cmds.h
index 71113cd7efa4..0f5908958f05 100644
--- a/include/block/block-hmp-cmds.h
+++ b/include/block/block-hmp-cmds.h
@@ -16,41 +16,42 @@
 #define BLOCK_BLOCK_HMP_CMDS_H
 
 #include "qemu/coroutine.h"
+#include "monitor/hmp.h"
 
-void hmp_drive_add(Monitor *mon, const QDict *qdict);
+void hmp_drive_add(MonitorHMP *hmp, const QDict *qdict);
 
-void hmp_commit(Monitor *mon, const QDict *qdict);
-void hmp_drive_del(Monitor *mon, const QDict *qdict);
+void hmp_commit(MonitorHMP *hmp, const QDict *qdict);
+void hmp_drive_del(MonitorHMP *hmp, const QDict *qdict);
 
-void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
-void hmp_drive_backup(Monitor *mon, const QDict *qdict);
+void hmp_drive_mirror(MonitorHMP *hmp, const QDict *qdict);
+void hmp_drive_backup(MonitorHMP *hmp, const QDict *qdict);
 
-void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
-void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
-void hmp_block_job_pause(Monitor *mon, const QDict *qdict);
-void hmp_block_job_resume(Monitor *mon, const QDict *qdict);
-void hmp_block_job_complete(Monitor *mon, const QDict *qdict);
+void hmp_block_job_set_speed(MonitorHMP *hmp, const QDict *qdict);
+void hmp_block_job_cancel(MonitorHMP *hmp, const QDict *qdict);
+void hmp_block_job_pause(MonitorHMP *hmp, const QDict *qdict);
+void hmp_block_job_resume(MonitorHMP *hmp, const QDict *qdict);
+void hmp_block_job_complete(MonitorHMP *hmp, const QDict *qdict);
 
-void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
-void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict);
-void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict);
+void hmp_snapshot_blkdev(MonitorHMP *hmp, const QDict *qdict);
+void hmp_snapshot_blkdev_internal(MonitorHMP *hmp, const QDict *qdict);
+void hmp_snapshot_delete_blkdev_internal(MonitorHMP *hmp, const QDict *qdict);
 
-void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
-void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
-void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict);
-void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
+void hmp_nbd_server_start(MonitorHMP *hmp, const QDict *qdict);
+void hmp_nbd_server_add(MonitorHMP *hmp, const QDict *qdict);
+void hmp_nbd_server_remove(MonitorHMP *hmp, const QDict *qdict);
+void hmp_nbd_server_stop(MonitorHMP *hmp, const QDict *qdict);
 
-void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict);
-void hmp_block_stream(Monitor *mon, const QDict *qdict);
-void hmp_block_passwd(Monitor *mon, const QDict *qdict);
-void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict);
-void hmp_eject(Monitor *mon, const QDict *qdict);
+void coroutine_fn hmp_block_resize(MonitorHMP *hmp, const QDict *qdict);
+void hmp_block_stream(MonitorHMP *hmp, const QDict *qdict);
+void hmp_block_passwd(MonitorHMP *hmp, const QDict *qdict);
+void hmp_block_set_io_throttle(MonitorHMP *hmp, const QDict *qdict);
+void hmp_eject(MonitorHMP *hmp, const QDict *qdict);
 
-void hmp_qemu_io(Monitor *mon, const QDict *qdict);
+void hmp_qemu_io(MonitorHMP *hmp, const QDict *qdict);
 
-void hmp_info_block(Monitor *mon, const QDict *qdict);
-void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
-void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
-void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
+void hmp_info_block(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_blockstats(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_block_jobs(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_snapshots(MonitorHMP *hmp, const QDict *qdict);
 
 #endif
diff --git a/include/hw/usb/usb.h b/include/hw/usb/usb.h
index 78e2ceedd7fd..cbd4711933e8 100644
--- a/include/hw/usb/usb.h
+++ b/include/hw/usb/usb.h
@@ -31,6 +31,7 @@
 #include "qemu/queue.h"
 #include "qom/object.h"
 #include "qapi/error.h"
+#include "monitor/hmp.h"
 
 /* Constants related to the USB / PCI interaction */
 #define USB_SBRN    0x60 /* Serial Bus Release Number Register */
@@ -466,7 +467,7 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream);
 void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p);
 
 /* usb-linux.c */
-void hmp_info_usbhost(Monitor *mon, const QDict *qdict);
+void hmp_info_usbhost(MonitorHMP *hmp, const QDict *qdict);
 
 /* usb ports of the VM */
 
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index 166cd4100c63..7a270ad3f25c 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -22,7 +22,7 @@
 OBJECT_DECLARE_TYPE(MonitorHMP, MonitorHMPClass, MONITOR_HMP);
 
 #define HMP_STUB(cmd) \
-    void hmp_##cmd(Monitor *mon, const QDict *qdict) \
+    void hmp_##cmd(MonitorHMP *hmp, const QDict *qdict) \
     { \
         g_assert_not_reached(); \
     }
@@ -46,7 +46,7 @@ int monitor_hmp_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
                               void *opaque);
 
 void monitor_register_hmp(const char *name, bool info,
-                          void (*cmd)(Monitor *mon, const QDict *qdict));
+                          void (*cmd)(MonitorHMP *mon, const QDict *qdict));
 void monitor_register_hmp_info_hrt(const char *name,
                                    HumanReadableText *(*handler)(Error **errp));
 
@@ -58,58 +58,58 @@ bool hmp_handle_error(Monitor *mon, Error *err);
 void hmp_help_cmd(Monitor *mon, const char *name);
 strList *hmp_split_at_comma(const char *str);
 
-void hmp_info_name(Monitor *mon, const QDict *qdict);
-void hmp_info_version(Monitor *mon, const QDict *qdict);
-void hmp_info_kvm(Monitor *mon, const QDict *qdict);
-void hmp_info_accelerators(Monitor *mon, const QDict *qdict);
-void hmp_info_status(Monitor *mon, const QDict *qdict);
-void hmp_info_uuid(Monitor *mon, const QDict *qdict);
-void hmp_info_chardev(Monitor *mon, const QDict *qdict);
-void hmp_info_mice(Monitor *mon, const QDict *qdict);
-void hmp_info_migrate(Monitor *mon, const QDict *qdict);
-void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
-void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict);
-void hmp_info_cpus(Monitor *mon, const QDict *qdict);
-void hmp_info_vnc(Monitor *mon, const QDict *qdict);
-void hmp_info_spice(Monitor *mon, const QDict *qdict);
-void hmp_info_balloon(Monitor *mon, const QDict *qdict);
-void hmp_info_pci(Monitor *mon, const QDict *qdict);
-void hmp_info_tpm(Monitor *mon, const QDict *qdict);
-void hmp_info_iothreads(Monitor *mon, const QDict *qdict);
-void hmp_quit(Monitor *mon, const QDict *qdict);
-void hmp_stop(Monitor *mon, const QDict *qdict);
-void hmp_sync_profile(Monitor *mon, const QDict *qdict);
-void hmp_system_reset(Monitor *mon, const QDict *qdict);
-void hmp_system_powerdown(Monitor *mon, const QDict *qdict);
-void hmp_exit_preconfig(Monitor *mon, const QDict *qdict);
-void hmp_announce_self(Monitor *mon, const QDict *qdict);
-void hmp_cpu(Monitor *mon, const QDict *qdict);
-void hmp_memsave(Monitor *mon, const QDict *qdict);
-void hmp_pmemsave(Monitor *mon, const QDict *qdict);
-void hmp_ringbuf_write(Monitor *mon, const QDict *qdict);
-void hmp_ringbuf_read(Monitor *mon, const QDict *qdict);
-void hmp_cont(Monitor *mon, const QDict *qdict);
-void hmp_system_wakeup(Monitor *mon, const QDict *qdict);
-void hmp_nmi(Monitor *mon, const QDict *qdict);
-void hmp_info_network(Monitor *mon, const QDict *qdict);
-void hmp_set_link(Monitor *mon, const QDict *qdict);
-void hmp_balloon(Monitor *mon, const QDict *qdict);
-void hmp_loadvm(Monitor *mon, const QDict *qdict);
-void hmp_savevm(Monitor *mon, const QDict *qdict);
-void hmp_delvm(Monitor *mon, const QDict *qdict);
-void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
-void hmp_migrate_continue(Monitor *mon, const QDict *qdict);
-void hmp_migrate_incoming(Monitor *mon, const QDict *qdict);
-void hmp_migrate_recover(Monitor *mon, const QDict *qdict);
-void hmp_migrate_pause(Monitor *mon, const QDict *qdict);
-void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict);
-void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict);
-void hmp_client_migrate_info(Monitor *mon, const QDict *qdict);
-void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict);
-void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict);
-void hmp_set_password(Monitor *mon, const QDict *qdict);
-void hmp_expire_password(Monitor *mon, const QDict *qdict);
-void hmp_change(Monitor *mon, const QDict *qdict);
+void hmp_info_name(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_version(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_kvm(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_accelerators(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_status(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_uuid(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_chardev(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_mice(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_migrate(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_migrate_capabilities(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_migrate_parameters(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_cpus(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_vnc(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_spice(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_balloon(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_tpm(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_iothreads(MonitorHMP *hmp, const QDict *qdict);
+void hmp_quit(MonitorHMP *hmp, const QDict *qdict);
+void hmp_stop(MonitorHMP *hmp, const QDict *qdict);
+void hmp_sync_profile(MonitorHMP *hmp, const QDict *qdict);
+void hmp_system_reset(MonitorHMP *hmp, const QDict *qdict);
+void hmp_system_powerdown(MonitorHMP *hmp, const QDict *qdict);
+void hmp_exit_preconfig(MonitorHMP *hmp, const QDict *qdict);
+void hmp_announce_self(MonitorHMP *hmp, const QDict *qdict);
+void hmp_cpu(MonitorHMP *hmp, const QDict *qdict);
+void hmp_memsave(MonitorHMP *hmp, const QDict *qdict);
+void hmp_pmemsave(MonitorHMP *hmp, const QDict *qdict);
+void hmp_ringbuf_write(MonitorHMP *hmp, const QDict *qdict);
+void hmp_ringbuf_read(MonitorHMP *hmp, const QDict *qdict);
+void hmp_cont(MonitorHMP *hmp, const QDict *qdict);
+void hmp_system_wakeup(MonitorHMP *hmp, const QDict *qdict);
+void hmp_nmi(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_network(MonitorHMP *hmp, const QDict *qdict);
+void hmp_set_link(MonitorHMP *hmp, const QDict *qdict);
+void hmp_balloon(MonitorHMP *hmp, const QDict *qdict);
+void hmp_loadvm(MonitorHMP *hmp, const QDict *qdict);
+void hmp_savevm(MonitorHMP *hmp, const QDict *qdict);
+void hmp_delvm(MonitorHMP *hmp, const QDict *qdict);
+void hmp_migrate_cancel(MonitorHMP *hmp, const QDict *qdict);
+void hmp_migrate_continue(MonitorHMP *hmp, const QDict *qdict);
+void hmp_migrate_incoming(MonitorHMP *hmp, const QDict *qdict);
+void hmp_migrate_recover(MonitorHMP *hmp, const QDict *qdict);
+void hmp_migrate_pause(MonitorHMP *hmp, const QDict *qdict);
+void hmp_migrate_set_capability(MonitorHMP *hmp, const QDict *qdict);
+void hmp_migrate_set_parameter(MonitorHMP *hmp, const QDict *qdict);
+void hmp_client_migrate_info(MonitorHMP *hmp, const QDict *qdict);
+void hmp_migrate_start_postcopy(MonitorHMP *hmp, const QDict *qdict);
+void hmp_x_colo_lost_heartbeat(MonitorHMP *hmp, const QDict *qdict);
+void hmp_set_password(MonitorHMP *hmp, const QDict *qdict);
+void hmp_expire_password(MonitorHMP *hmp, const QDict *qdict);
+void hmp_change(MonitorHMP *hmp, const QDict *qdict);
 #ifdef CONFIG_VNC
 void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
                     const char *arg, const char *read_only, bool force,
@@ -118,101 +118,101 @@ void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
 void hmp_change_medium(Monitor *mon, const char *device, const char *target,
                        const char *arg, const char *read_only, bool force,
                        Error **errp);
-void hmp_migrate(Monitor *mon, const QDict *qdict);
-void hmp_device_add(Monitor *mon, const QDict *qdict);
-void hmp_device_del(Monitor *mon, const QDict *qdict);
-void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
-void hmp_netdev_add(Monitor *mon, const QDict *qdict);
-void hmp_netdev_del(Monitor *mon, const QDict *qdict);
-void hmp_getfd(Monitor *mon, const QDict *qdict);
-void hmp_closefd(Monitor *mon, const QDict *qdict);
-void hmp_mouse_move(Monitor *mon, const QDict *qdict);
-void hmp_mouse_button(Monitor *mon, const QDict *qdict);
-void hmp_mouse_set(Monitor *mon, const QDict *qdict);
-void hmp_sendkey(Monitor *mon, const QDict *qdict);
-void coroutine_fn hmp_screendump(Monitor *mon, const QDict *qdict);
-void hmp_chardev_add(Monitor *mon, const QDict *qdict);
-void hmp_chardev_change(Monitor *mon, const QDict *qdict);
-void hmp_chardev_remove(Monitor *mon, const QDict *qdict);
-void hmp_chardev_send_break(Monitor *mon, const QDict *qdict);
-void hmp_object_add(Monitor *mon, const QDict *qdict);
-void hmp_object_del(Monitor *mon, const QDict *qdict);
-void hmp_info_memdev(Monitor *mon, const QDict *qdict);
-void hmp_info_memory_devices(Monitor *mon, const QDict *qdict);
-void hmp_qom_list(Monitor *mon, const QDict *qdict);
-void hmp_qom_get(Monitor *mon, const QDict *qdict);
-void hmp_qom_set(Monitor *mon, const QDict *qdict);
-void hmp_info_qom_tree(Monitor *mon, const QDict *dict);
-void hmp_virtio_query(Monitor *mon, const QDict *qdict);
-void hmp_virtio_status(Monitor *mon, const QDict *qdict);
-void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict);
-void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict);
-void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict);
-void hmp_xen_event_inject(Monitor *mon, const QDict *qdict);
-void hmp_xen_event_list(Monitor *mon, const QDict *qdict);
-void hmp_rocker(Monitor *mon, const QDict *qdict);
-void hmp_rocker_ports(Monitor *mon, const QDict *qdict);
-void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict);
-void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict);
-void hmp_info_dump(Monitor *mon, const QDict *qdict);
-void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict);
-void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict);
-void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict);
-void hmp_info_replay(Monitor *mon, const QDict *qdict);
-void hmp_replay_break(Monitor *mon, const QDict *qdict);
-void hmp_replay_delete_break(Monitor *mon, const QDict *qdict);
-void hmp_replay_seek(Monitor *mon, const QDict *qdict);
-void hmp_info_dirty_rate(Monitor *mon, const QDict *qdict);
-void hmp_calc_dirty_rate(Monitor *mon, const QDict *qdict);
-void hmp_set_vcpu_dirty_limit(Monitor *mon, const QDict *qdict);
-void hmp_cancel_vcpu_dirty_limit(Monitor *mon, const QDict *qdict);
-void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict *qdict);
+void hmp_migrate(MonitorHMP *hmp, const QDict *qdict);
+void hmp_device_add(MonitorHMP *hmp, const QDict *qdict);
+void hmp_device_del(MonitorHMP *hmp, const QDict *qdict);
+void hmp_dump_guest_memory(MonitorHMP *hmp, const QDict *qdict);
+void hmp_netdev_add(MonitorHMP *hmp, const QDict *qdict);
+void hmp_netdev_del(MonitorHMP *hmp, const QDict *qdict);
+void hmp_getfd(MonitorHMP *hmp, const QDict *qdict);
+void hmp_closefd(MonitorHMP *hmp, const QDict *qdict);
+void hmp_mouse_move(MonitorHMP *hmp, const QDict *qdict);
+void hmp_mouse_button(MonitorHMP *hmp, const QDict *qdict);
+void hmp_mouse_set(MonitorHMP *hmp, const QDict *qdict);
+void hmp_sendkey(MonitorHMP *hmp, const QDict *qdict);
+void coroutine_fn hmp_screendump(MonitorHMP *hmp, const QDict *qdict);
+void hmp_chardev_add(MonitorHMP *hmp, const QDict *qdict);
+void hmp_chardev_change(MonitorHMP *hmp, const QDict *qdict);
+void hmp_chardev_remove(MonitorHMP *hmp, const QDict *qdict);
+void hmp_chardev_send_break(MonitorHMP *hmp, const QDict *qdict);
+void hmp_object_add(MonitorHMP *hmp, const QDict *qdict);
+void hmp_object_del(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_memdev(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_memory_devices(MonitorHMP *hmp, const QDict *qdict);
+void hmp_qom_list(MonitorHMP *hmp, const QDict *qdict);
+void hmp_qom_get(MonitorHMP *hmp, const QDict *qdict);
+void hmp_qom_set(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_qom_tree(MonitorHMP *hmp, const QDict *dict);
+void hmp_virtio_query(MonitorHMP *hmp, const QDict *qdict);
+void hmp_virtio_status(MonitorHMP *hmp, const QDict *qdict);
+void hmp_virtio_queue_status(MonitorHMP *hmp, const QDict *qdict);
+void hmp_vhost_queue_status(MonitorHMP *hmp, const QDict *qdict);
+void hmp_virtio_queue_element(MonitorHMP *hmp, const QDict *qdict);
+void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict);
+void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict);
+void hmp_rocker(MonitorHMP *hmp, const QDict *qdict);
+void hmp_rocker_ports(MonitorHMP *hmp, const QDict *qdict);
+void hmp_rocker_of_dpa_flows(MonitorHMP *hmp, const QDict *qdict);
+void hmp_rocker_of_dpa_groups(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_dump(MonitorHMP *hmp, const QDict *qdict);
+void hmp_hotpluggable_cpus(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_vm_generation_id(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_memory_size_summary(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_replay(MonitorHMP *hmp, const QDict *qdict);
+void hmp_replay_break(MonitorHMP *hmp, const QDict *qdict);
+void hmp_replay_delete_break(MonitorHMP *hmp, const QDict *qdict);
+void hmp_replay_seek(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_dirty_rate(MonitorHMP *hmp, const QDict *qdict);
+void hmp_calc_dirty_rate(MonitorHMP *hmp, const QDict *qdict);
+void hmp_set_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict);
+void hmp_cancel_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict);
 void hmp_human_readable_text_helper(Monitor *mon,
                                     HumanReadableText *(*qmp_handler)(Error **));
-void hmp_info_stats(Monitor *mon, const QDict *qdict);
-void hmp_one_insn_per_tb(Monitor *mon, const QDict *qdict);
-void hmp_watchdog_action(Monitor *mon, const QDict *qdict);
-void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict);
-void hmp_info_capture(Monitor *mon, const QDict *qdict);
-void hmp_stopcapture(Monitor *mon, const QDict *qdict);
-void hmp_wavcapture(Monitor *mon, const QDict *qdict);
-void hmp_trace_event(Monitor *mon, const QDict *qdict);
-void hmp_trace_file(Monitor *mon, const QDict *qdict);
-void hmp_info_trace_events(Monitor *mon, const QDict *qdict);
-void hmp_help(Monitor *mon, const QDict *qdict);
-void hmp_clear(Monitor *mon, const QDict *qdict);
-void hmp_info_help(Monitor *mon, const QDict *qdict);
-void hmp_info_sync_profile(Monitor *mon, const QDict *qdict);
-void hmp_info_history(Monitor *mon, const QDict *qdict);
-void hmp_logfile(Monitor *mon, const QDict *qdict);
-void hmp_log(Monitor *mon, const QDict *qdict);
-void hmp_gdbserver(Monitor *mon, const QDict *qdict);
-void hmp_print(Monitor *mon, const QDict *qdict);
-void hmp_sum(Monitor *mon, const QDict *qdict);
-void hmp_ioport_read(Monitor *mon, const QDict *qdict);
-void hmp_ioport_write(Monitor *mon, const QDict *qdict);
-void hmp_boot_set(Monitor *mon, const QDict *qdict);
-void hmp_info_mtree(Monitor *mon, const QDict *qdict);
-void hmp_info_cryptodev(Monitor *mon, const QDict *qdict);
-void hmp_dumpdtb(Monitor *mon, const QDict *qdict);
-void hmp_info_firmware_log(Monitor *mon, const QDict *qdict);
-void hmp_info_mem(Monitor *mon, const QDict *qdict);
-void hmp_info_tlb(Monitor *mon, const QDict *qdict);
-void hmp_mce(Monitor *mon, const QDict *qdict);
-void hmp_info_local_apic(Monitor *mon, const QDict *qdict);
-void hmp_info_sev(Monitor *mon, const QDict *qdict);
-void hmp_info_sgx(Monitor *mon, const QDict *qdict);
-void hmp_info_via(Monitor *mon, const QDict *qdict);
-void hmp_memory_dump(Monitor *mon, const QDict *qdict);
-void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict);
-void hmp_info_registers(Monitor *mon, const QDict *qdict);
-void hmp_gva2gpa(Monitor *mon, const QDict *qdict);
-void hmp_gpa2hva(Monitor *mon, const QDict *qdict);
-void hmp_gpa2hpa(Monitor *mon, const QDict *qdict);
+void hmp_info_stats(MonitorHMP *hmp, const QDict *qdict);
+void hmp_one_insn_per_tb(MonitorHMP *hmp, const QDict *qdict);
+void hmp_watchdog_action(MonitorHMP *hmp, const QDict *qdict);
+void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_capture(MonitorHMP *hmp, const QDict *qdict);
+void hmp_stopcapture(MonitorHMP *hmp, const QDict *qdict);
+void hmp_wavcapture(MonitorHMP *hmp, const QDict *qdict);
+void hmp_trace_event(MonitorHMP *hmp, const QDict *qdict);
+void hmp_trace_file(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_trace_events(MonitorHMP *hmp, const QDict *qdict);
+void hmp_help(MonitorHMP *hmp, const QDict *qdict);
+void hmp_clear(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_help(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_sync_profile(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_history(MonitorHMP *hmp, const QDict *qdict);
+void hmp_logfile(MonitorHMP *hmp, const QDict *qdict);
+void hmp_log(MonitorHMP *hmp, const QDict *qdict);
+void hmp_gdbserver(MonitorHMP *hmp, const QDict *qdict);
+void hmp_print(MonitorHMP *hmp, const QDict *qdict);
+void hmp_sum(MonitorHMP *hmp, const QDict *qdict);
+void hmp_ioport_read(MonitorHMP *hmp, const QDict *qdict);
+void hmp_ioport_write(MonitorHMP *hmp, const QDict *qdict);
+void hmp_boot_set(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_mtree(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_cryptodev(MonitorHMP *hmp, const QDict *qdict);
+void hmp_dumpdtb(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_firmware_log(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict);
+void hmp_mce(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_local_apic(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_sev(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_sgx(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_via(MonitorHMP *hmp, const QDict *qdict);
+void hmp_memory_dump(MonitorHMP *hmp, const QDict *qdict);
+void hmp_physical_memory_dump(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_registers(MonitorHMP *hmp, const QDict *qdict);
+void hmp_gva2gpa(MonitorHMP *hmp, const QDict *qdict);
+void hmp_gpa2hva(MonitorHMP *hmp, const QDict *qdict);
+void hmp_gpa2hpa(MonitorHMP *hmp, const QDict *qdict);
 
-void hmp_dump_skeys(Monitor *mon, const QDict *qdict);
-void hmp_info_skeys(Monitor *mon, const QDict *qdict);
-void hmp_info_cmma(Monitor *mon, const QDict *qdict);
-void hmp_migrationmode(Monitor *mon, const QDict *qdict);
+void hmp_dump_skeys(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_skeys(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_cmma(MonitorHMP *hmp, const QDict *qdict);
+void hmp_migrationmode(MonitorHMP *hmp, const QDict *qdict);
 
 #endif
diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h
index f85f25738d58..8f7e2f616cf3 100644
--- a/include/monitor/qdev.h
+++ b/include/monitor/qdev.h
@@ -2,11 +2,12 @@
 #define MONITOR_QDEV_H
 
 #include "hw/core/qdev.h"
+#include "monitor/hmp.h"
 
 /*** monitor commands ***/
 
-void hmp_info_qtree(Monitor *mon, const QDict *qdict);
-void hmp_info_qdm(Monitor *mon, const QDict *qdict);
+void hmp_info_qtree(MonitorHMP *hmp, const QDict *qdict);
+void hmp_info_qdm(MonitorHMP *hmp, const QDict *qdict);
 void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp);
 
 int qdev_device_help(QemuOpts *opts);
diff --git a/include/net/net.h b/include/net/net.h
index a7c49c543783..626b99794806 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -5,6 +5,7 @@
 #include "qapi/qapi-types-net.h"
 #include "net/queue.h"
 #include "hw/core/qdev-properties-system.h"
+#include "monitor/hmp.h"
 
 #define MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
 #define MAC_ARG(x) ((uint8_t *)(x))[0], ((uint8_t *)(x))[1], \
@@ -318,8 +319,8 @@ void net_init_clients(void);
 void net_check_clients(void);
 void net_client_set_link(NetClientState **ncs, int queues, bool up);
 void net_cleanup(void);
-void hmp_host_net_add(Monitor *mon, const QDict *qdict);
-void hmp_host_net_remove(Monitor *mon, const QDict *qdict);
+void hmp_host_net_add(MonitorHMP *hmp, const QDict *qdict);
+void hmp_host_net_remove(MonitorHMP *hmp, const QDict *qdict);
 void netdev_add(QemuOpts *opts, Error **errp);
 
 int net_hub_id_for_client(NetClientState *nc, int *id);
diff --git a/include/net/slirp.h b/include/net/slirp.h
index bad3e1e2416b..38859edf58ae 100644
--- a/include/net/slirp.h
+++ b/include/net/slirp.h
@@ -24,13 +24,13 @@
 #ifndef QEMU_NET_SLIRP_H
 #define QEMU_NET_SLIRP_H
 
-
 #ifdef CONFIG_SLIRP
+#include "monitor/hmp.h"
 
-void hmp_hostfwd_add(Monitor *mon, const QDict *qdict);
-void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict);
+void hmp_hostfwd_add(MonitorHMP *hmp, const QDict *qdict);
+void hmp_hostfwd_remove(MonitorHMP *hmp, const QDict *qdict);
 
-void hmp_info_usernet(Monitor *mon, const QDict *qdict);
+void hmp_info_usernet(MonitorHMP *hmp, const QDict *qdict);
 
 #endif
 
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index b360f49efeaf..567abab321cc 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -856,8 +856,9 @@ struct DirtyRateInfo *qmp_query_dirty_rate(bool has_calc_time_unit,
         has_calc_time_unit ? calc_time_unit : TIME_UNIT_SECOND);
 }
 
-void hmp_info_dirty_rate(Monitor *mon, const QDict *qdict)
+void hmp_info_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     DirtyRateInfo *info = query_dirty_rate_info(TIME_UNIT_SECOND);
 
     monitor_printf(mon, "Status: %s\n",
@@ -891,8 +892,9 @@ void hmp_info_dirty_rate(Monitor *mon, const QDict *qdict)
     g_free(info);
 }
 
-void hmp_calc_dirty_rate(Monitor *mon, const QDict *qdict)
+void hmp_calc_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     int64_t sec = qdict_get_try_int(qdict, "second", 0);
     int64_t sample_pages = qdict_get_try_int(qdict, "sample_pages_per_GB", -1);
     bool has_sample_pages = (sample_pages != -1);
diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c
index ad68fa23aa4b..8d2e8735277e 100644
--- a/migration/migration-hmp-cmds.c
+++ b/migration/migration-hmp-cmds.c
@@ -135,8 +135,9 @@ static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info)
     }
 }
 
-void hmp_info_migrate(Monitor *mon, const QDict *qdict)
+void hmp_info_migrate(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     bool show_all = qdict_get_try_bool(qdict, "all", false);
     MigrationInfo *info;
 
@@ -297,8 +298,9 @@ out:
     qapi_free_MigrationInfo(info);
 }
 
-void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
+void hmp_info_migrate_capabilities(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     MigrationCapabilityStatusList *caps, *cap;
 
     caps = qmp_query_migrate_capabilities(NULL);
@@ -326,8 +328,9 @@ static void monitor_print_cpr_exec_command(Monitor *mon, strList *args)
     monitor_printf(mon, "\n");
 }
 
-void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
+void hmp_info_migrate_parameters(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     MigrationParameters *params;
     MigrationState *s = migrate_get_current();
 
@@ -473,8 +476,9 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
     qapi_free_MigrationParameters(params);
 }
 
-void hmp_loadvm(Monitor *mon, const QDict *qdict)
+void hmp_loadvm(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     RunState saved_state = runstate_get();
 
     const char *name = qdict_get_str(qdict, "name");
@@ -489,8 +493,9 @@ void hmp_loadvm(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_savevm(Monitor *mon, const QDict *qdict)
+void hmp_savevm(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     save_snapshot(qdict_get_try_str(qdict, "name"),
@@ -498,8 +503,9 @@ void hmp_savevm(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_delvm(Monitor *mon, const QDict *qdict)
+void hmp_delvm(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *name = qdict_get_str(qdict, "name");
 
@@ -507,13 +513,14 @@ void hmp_delvm(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
+void hmp_migrate_cancel(MonitorHMP *hmp, const QDict *qdict)
 {
     qmp_migrate_cancel(NULL);
 }
 
-void hmp_migrate_continue(Monitor *mon, const QDict *qdict)
+void hmp_migrate_continue(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *state = qdict_get_str(qdict, "state");
     int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err);
@@ -525,8 +532,9 @@ void hmp_migrate_continue(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
+void hmp_migrate_incoming(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *uri = qdict_get_str(qdict, "uri");
     MigrationChannelList *caps = NULL;
@@ -544,8 +552,9 @@ end:
     hmp_handle_error(mon, err);
 }
 
-void hmp_migrate_recover(Monitor *mon, const QDict *qdict)
+void hmp_migrate_recover(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *uri = qdict_get_str(qdict, "uri");
 
@@ -554,8 +563,9 @@ void hmp_migrate_recover(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_migrate_pause(Monitor *mon, const QDict *qdict)
+void hmp_migrate_pause(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_migrate_pause(&err);
@@ -564,8 +574,9 @@ void hmp_migrate_pause(Monitor *mon, const QDict *qdict)
 }
 
 
-void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
+void hmp_migrate_set_capability(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *cap = qdict_get_str(qdict, "capability");
     bool state = qdict_get_bool(qdict, "state");
     Error *err = NULL;
@@ -589,8 +600,9 @@ end:
     hmp_handle_error(mon, err);
 }
 
-void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
+void hmp_migrate_set_parameter(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *param = qdict_get_str(qdict, "parameter");
     const char *valuestr = qdict_get_str(qdict, "value");
     Visitor *v = string_input_visitor_new(valuestr);
@@ -790,16 +802,18 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict)
+void hmp_migrate_start_postcopy(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     qmp_migrate_start_postcopy(&err);
     hmp_handle_error(mon, err);
 }
 
 #ifdef CONFIG_REPLICATION
-void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict)
+void hmp_x_colo_lost_heartbeat(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_x_colo_lost_heartbeat(&err);
@@ -833,8 +847,9 @@ static void hmp_migrate_status_cb(void *opaque)
     qapi_free_MigrationInfo(info);
 }
 
-void hmp_migrate(Monitor *mon, const QDict *qdict)
+void hmp_migrate(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     bool detach = qdict_get_try_bool(qdict, "detach", false);
     bool resume = qdict_get_try_bool(qdict, "resume", false);
     const char *uri = qdict_get_str(qdict, "uri");
@@ -873,7 +888,6 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)
 
     if (!detach) {
         HMPMigrationStatus *status;
-        MonitorHMP *hmp = MONITOR_HMP(mon);
 
         if (!hmp->use_readline) {
             monitor_printf(mon, "terminal does not allow synchronous "
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 6718fec97047..afe4817b4056 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -103,8 +103,9 @@ strList *hmp_split_at_comma(const char *str)
     return res;
 }
 
-void hmp_info_name(Monitor *mon, const QDict *qdict)
+void hmp_info_name(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     NameInfo *info;
 
     info = qmp_query_name(NULL);
@@ -114,8 +115,9 @@ void hmp_info_name(Monitor *mon, const QDict *qdict)
     qapi_free_NameInfo(info);
 }
 
-void hmp_info_version(Monitor *mon, const QDict *qdict)
+void hmp_info_version(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     VersionInfo *info;
 
     info = qmp_query_version(NULL);
@@ -127,22 +129,23 @@ void hmp_info_version(Monitor *mon, const QDict *qdict)
     qapi_free_VersionInfo(info);
 }
 
-void hmp_quit(Monitor *mon, const QDict *qdict)
+void hmp_quit(MonitorHMP *hmp, const QDict *qdict)
 {
-    MonitorHMP *hmp = MONITOR_HMP(mon);
+    Monitor *mon = MONITOR(hmp);
     if (hmp->use_readline) {
         monitor_suspend(mon);
     }
     qmp_quit(NULL);
 }
 
-void hmp_stop(Monitor *mon, const QDict *qdict)
+void hmp_stop(MonitorHMP *hmp, const QDict *qdict)
 {
     qmp_stop(NULL);
 }
 
-void hmp_sync_profile(Monitor *mon, const QDict *qdict)
+void hmp_sync_profile(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *op = qdict_get_try_str(qdict, "op");
 
     if (op == NULL) {
@@ -166,16 +169,18 @@ void hmp_sync_profile(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_exit_preconfig(Monitor *mon, const QDict *qdict)
+void hmp_exit_preconfig(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_x_exit_preconfig(&err);
     hmp_handle_error(mon, err);
 }
 
-void hmp_cpu(Monitor *mon, const QDict *qdict)
+void hmp_cpu(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     int64_t cpu_index;
 
     /* XXX: drop the monitor_set_cpu() usage when all HMP commands that
@@ -186,16 +191,18 @@ void hmp_cpu(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_cont(Monitor *mon, const QDict *qdict)
+void hmp_cont(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_cont(&err);
     hmp_handle_error(mon, err);
 }
 
-void hmp_change(Monitor *mon, const QDict *qdict)
+void hmp_change(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     const char *target = qdict_get_str(qdict, "target");
     const char *arg = qdict_get_try_str(qdict, "arg");
@@ -216,8 +223,9 @@ void hmp_change(Monitor *mon, const QDict *qdict)
 }
 
 #ifdef CONFIG_POSIX
-void hmp_getfd(Monitor *mon, const QDict *qdict)
+void hmp_getfd(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *fdname = qdict_get_str(qdict, "fdname");
     Error *err = NULL;
 
@@ -226,8 +234,9 @@ void hmp_getfd(Monitor *mon, const QDict *qdict)
 }
 #endif
 
-void hmp_closefd(Monitor *mon, const QDict *qdict)
+void hmp_closefd(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *fdname = qdict_get_str(qdict, "fdname");
     Error *err = NULL;
 
@@ -235,8 +244,9 @@ void hmp_closefd(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
+void hmp_info_iothreads(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
     IOThreadInfoList *info;
     IOThreadInfo *value;
@@ -256,13 +266,15 @@ void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
     qapi_free_IOThreadInfoList(info_list);
 }
 
-void hmp_help(Monitor *mon, const QDict *qdict)
+void hmp_help(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     hmp_help_cmd(mon, qdict_get_try_str(qdict, "name"));
 }
 
-void hmp_clear(Monitor *mon, const QDict *qdict)
+void hmp_clear(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     /*
      * Send an ANSI escape sequence:
      * "\x1b[H" - move cursor to top-left
@@ -272,12 +284,13 @@ void hmp_clear(Monitor *mon, const QDict *qdict)
     monitor_printf(mon, "\x1b[H\x1b[2J\x1b[3J");
 }
 
-void hmp_info_help(Monitor *mon, const QDict *qdict)
+void hmp_info_help(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     hmp_help_cmd(mon, "info");
 }
 
-void hmp_info_sync_profile(Monitor *mon, const QDict *qdict)
+void hmp_info_sync_profile(MonitorHMP *hmp, const QDict *qdict)
 {
     int64_t max = qdict_get_try_int(qdict, "max", 10);
     bool mean = qdict_get_try_bool(qdict, "mean", false);
@@ -288,9 +301,9 @@ void hmp_info_sync_profile(Monitor *mon, const QDict *qdict)
     qsp_report(max, sort_by, coalesce);
 }
 
-void hmp_info_history(Monitor *mon, const QDict *qdict)
+void hmp_info_history(MonitorHMP *hmp, const QDict *qdict)
 {
-    MonitorHMP *hmp = MONITOR_HMP(mon);
+    Monitor *mon = MONITOR(hmp);
     int i;
     const char *str;
 
@@ -308,7 +321,7 @@ void hmp_info_history(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_logfile(Monitor *mon, const QDict *qdict)
+void hmp_logfile(MonitorHMP *hmp, const QDict *qdict)
 {
     Error *err = NULL;
 
@@ -317,8 +330,9 @@ void hmp_logfile(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_log(Monitor *mon, const QDict *qdict)
+void hmp_log(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     int mask;
     const char *items = qdict_get_str(qdict, "items");
     Error *err = NULL;
@@ -338,8 +352,9 @@ void hmp_log(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_gdbserver(Monitor *mon, const QDict *qdict)
+void hmp_gdbserver(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *device = qdict_get_try_str(qdict, "device");
 
@@ -357,8 +372,9 @@ void hmp_gdbserver(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_print(Monitor *mon, const QDict *qdict)
+void hmp_print(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     int format = qdict_get_int(qdict, "format");
     hwaddr val = qdict_get_int(qdict, "val");
 
@@ -383,8 +399,9 @@ void hmp_print(Monitor *mon, const QDict *qdict)
     monitor_printf(mon, "\n");
 }
 
-void hmp_sum(Monitor *mon, const QDict *qdict)
+void hmp_sum(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     uint32_t addr;
     uint16_t sum;
     uint32_t start = qdict_get_int(qdict, "start");
@@ -401,8 +418,9 @@ void hmp_sum(Monitor *mon, const QDict *qdict)
     monitor_printf(mon, "%05d\n", sum);
 }
 
-void hmp_ioport_read(Monitor *mon, const QDict *qdict)
+void hmp_ioport_read(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     int size = qdict_get_int(qdict, "size");
     int addr = qdict_get_int(qdict, "addr");
     int has_index = qdict_haskey(qdict, "index");
@@ -435,7 +453,7 @@ void hmp_ioport_read(Monitor *mon, const QDict *qdict)
                    suffix, addr, size * 2, val);
 }
 
-void hmp_ioport_write(Monitor *mon, const QDict *qdict)
+void hmp_ioport_write(MonitorHMP *hmp, const QDict *qdict)
 {
     int size = qdict_get_int(qdict, "size");
     int addr = qdict_get_int(qdict, "addr");
@@ -457,8 +475,9 @@ void hmp_ioport_write(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_boot_set(Monitor *mon, const QDict *qdict)
+void hmp_boot_set(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *local_err = NULL;
     const char *bootdevice = qdict_get_str(qdict, "bootdevice");
 
@@ -470,7 +489,7 @@ void hmp_boot_set(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_info_mtree(Monitor *mon, const QDict *qdict)
+void hmp_info_mtree(MonitorHMP *hmp, const QDict *qdict)
 {
     bool flatview = qdict_get_try_bool(qdict, "flatview", false);
     bool dispatch_tree = qdict_get_try_bool(qdict, "dispatch_tree", false);
@@ -481,8 +500,9 @@ void hmp_info_mtree(Monitor *mon, const QDict *qdict)
 }
 
 #if defined(CONFIG_FDT)
-void hmp_dumpdtb(Monitor *mon, const QDict *qdict)
+void hmp_dumpdtb(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *filename = qdict_get_str(qdict, "filename");
     Error *local_err = NULL;
 
@@ -558,8 +578,9 @@ int monitor_get_cpu_index(Monitor *mon)
     return cs ? cs->cpu_index : UNASSIGNED_CPU_INDEX;
 }
 
-void hmp_info_registers(Monitor *mon, const QDict *qdict)
+void hmp_info_registers(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     bool all_cpus = qdict_get_try_bool(qdict, "cpustate_all", false);
     int vcpu = qdict_get_try_int(qdict, "vcpu", -1);
     CPUState *cs;
@@ -694,8 +715,9 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
     }
 }
 
-void hmp_memory_dump(Monitor *mon, const QDict *qdict)
+void hmp_memory_dump(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     int count = qdict_get_int(qdict, "count");
     int format = qdict_get_int(qdict, "format");
     int size = qdict_get_int(qdict, "size");
@@ -704,8 +726,9 @@ void hmp_memory_dump(Monitor *mon, const QDict *qdict)
     memory_dump(mon, count, format, size, addr, false);
 }
 
-void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
+void hmp_physical_memory_dump(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     int count = qdict_get_int(qdict, "count");
     int format = qdict_get_int(qdict, "format");
     int size = qdict_get_int(qdict, "size");
@@ -714,8 +737,9 @@ void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
     memory_dump(mon, count, format, size, addr, true);
 }
 
-void hmp_gpa2hva(Monitor *mon, const QDict *qdict)
+void hmp_gpa2hva(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     hwaddr addr = qdict_get_int(qdict, "addr");
     Error *local_err = NULL;
     MemoryRegion *mr = NULL;
@@ -734,8 +758,9 @@ void hmp_gpa2hva(Monitor *mon, const QDict *qdict)
     memory_region_unref(mr);
 }
 
-void hmp_gva2gpa(Monitor *mon, const QDict *qdict)
+void hmp_gva2gpa(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     vaddr addr = qdict_get_int(qdict, "addr");
     CPUState *cs = mon_get_cpu(mon);
     TranslateForDebugResult tres;
@@ -787,8 +812,9 @@ out:
     return ret;
 }
 
-void hmp_gpa2hpa(Monitor *mon, const QDict *qdict)
+void hmp_gpa2hpa(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     hwaddr addr = qdict_get_int(qdict, "addr");
     Error *local_err = NULL;
     MemoryRegion *mr = NULL;
diff --git a/monitor/hmp.c b/monitor/hmp.c
index b4d05d47c4bf..6e6334b64685 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -1228,12 +1228,12 @@ static void hmp_info_human_readable_text(Monitor *mon,
     monitor_puts(mon, info->human_readable_text);
 }
 
-static void handle_hmp_command_exec(Monitor *mon,
+static void handle_hmp_command_exec(MonitorHMP *mon,
                                     const HMPCommand *cmd,
                                     QDict *qdict)
 {
     if (cmd->cmd_info_hrt) {
-        hmp_info_human_readable_text(mon,
+        hmp_info_human_readable_text(MONITOR(mon),
                                      cmd->cmd_info_hrt);
     } else {
         cmd->cmd(mon, qdict);
@@ -1241,7 +1241,7 @@ static void handle_hmp_command_exec(Monitor *mon,
 }
 
 typedef struct HandleHmpCommandCo {
-    Monitor *mon;
+    MonitorHMP *mon;
     const HMPCommand *cmd;
     QDict *qdict;
     bool done;
@@ -1289,19 +1289,18 @@ void handle_hmp_command(MonitorHMP *hmp, const char *cmdline)
 
     if (!cmd->coroutine) {
         /* old_mon is non-NULL when called from qmp_human_monitor_command() */
-        Monitor *old_mon = monitor_set_cur(qemu_coroutine_self(),
-                                           &hmp->parent_obj);
-        handle_hmp_command_exec(&hmp->parent_obj, cmd, qdict);
+        Monitor *old_mon = monitor_set_cur(qemu_coroutine_self(), MONITOR(hmp));
+        handle_hmp_command_exec(hmp, cmd, qdict);
         monitor_set_cur(qemu_coroutine_self(), old_mon);
     } else {
         HandleHmpCommandCo data = {
-            .mon = &hmp->parent_obj,
+            .mon = hmp,
             .cmd = cmd,
             .qdict = qdict,
             .done = false,
         };
         Coroutine *co = qemu_coroutine_create(handle_hmp_command_co, &data);
-        monitor_set_cur(co, &hmp->parent_obj);
+        monitor_set_cur(co, MONITOR(hmp));
         aio_co_enter(qemu_get_aio_context(), co);
         AIO_WAIT_WHILE_UNLOCKED(NULL, !data.done);
     }
@@ -1689,7 +1688,7 @@ int hmp_compare_cmd(const char *name, const char *list)
 }
 
 void monitor_register_hmp(const char *name, bool info,
-                          void (*cmd)(Monitor *mon, const QDict *qdict))
+                          void (*cmd)(MonitorHMP *mon, const QDict *qdict))
 {
     HMPCommand *table = hmp_cmds_for_target(info);
 
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index ee9ba0c8231e..a0fa37c887ed 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -77,7 +77,7 @@ typedef struct HMPCommand {
     const char *params;
     const char *help;
     const char *flags; /* p=preconfig */
-    void (*cmd)(Monitor *mon, const QDict *qdict);
+    void (*cmd)(MonitorHMP *mon, const QDict *qdict);
     /*
      * If implementing a command that takes no arguments and simply
      * prints formatted data, then leave @cmd NULL, and then set
diff --git a/net/net-hmp-cmds.c b/net/net-hmp-cmds.c
index 52ac8da770d9..702103b6a920 100644
--- a/net/net-hmp-cmds.c
+++ b/net/net-hmp-cmds.c
@@ -45,8 +45,9 @@ static void hmp_print_client_info(Monitor *mon, NetworkClientInfo *ci)
     }
 }
 
-void hmp_info_network(Monitor *mon, const QDict *qdict)
+void hmp_info_network(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     g_autoptr(NetworkInfo) info = qmp_x_query_network(&err);
     NetHubInfoList *h;
@@ -83,8 +84,9 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_set_link(Monitor *mon, const QDict *qdict)
+void hmp_set_link(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *name = qdict_get_str(qdict, "name");
     bool up = qdict_get_bool(qdict, "up");
     Error *err = NULL;
@@ -94,7 +96,7 @@ void hmp_set_link(Monitor *mon, const QDict *qdict)
 }
 
 
-void hmp_announce_self(Monitor *mon, const QDict *qdict)
+void hmp_announce_self(MonitorHMP *hmp, const QDict *qdict)
 {
     const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
     const char *id = qdict_get_try_str(qdict, "id");
@@ -109,8 +111,9 @@ void hmp_announce_self(Monitor *mon, const QDict *qdict)
     qapi_free_AnnounceParameters(params);
 }
 
-void hmp_netdev_add(Monitor *mon, const QDict *qdict)
+void hmp_netdev_add(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     QemuOpts *opts;
     const char *type = qdict_get_try_str(qdict, "type");
@@ -133,8 +136,9 @@ out:
     hmp_handle_error(mon, err);
 }
 
-void hmp_netdev_del(Monitor *mon, const QDict *qdict)
+void hmp_netdev_del(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *id = qdict_get_str(qdict, "id");
     Error *err = NULL;
 
diff --git a/net/slirp.c b/net/slirp.c
index 9bf09a2c8bc9..d5c190b48b76 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -733,8 +733,9 @@ static SlirpState *slirp_lookup(Monitor *mon, const char *id)
     }
 }
 
-void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
+void hmp_hostfwd_remove(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     /* TODO: support removing unix fwd */
     struct sockaddr_in host_addr = {
         .sin_family = AF_INET,
@@ -957,8 +958,9 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
     return -1;
 }
 
-void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
+void hmp_hostfwd_add(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *redir_str;
     SlirpState *s;
     const char *arg1 = qdict_get_str(qdict, "arg1");
@@ -1224,8 +1226,9 @@ UsernetInfoList *qmp_x_query_usernet(Error **errp)
     return head;
 }
 
-void hmp_info_usernet(Monitor *mon, const QDict *qdict)
+void hmp_info_usernet(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     g_autoptr(UsernetInfoList) list = NULL;
     UsernetInfoList *entry;
 
diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c
index 47110ca58c0d..16847d1ce261 100644
--- a/qom/qom-hmp-cmds.c
+++ b/qom/qom-hmp-cmds.c
@@ -18,8 +18,9 @@
 #include "qom/object.h"
 #include "qom/object_interfaces.h"
 
-void hmp_qom_list(Monitor *mon, const QDict *qdict)
+void hmp_qom_list(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *path = qdict_get_try_str(qdict, "path");
     ObjectPropertyInfoList *list;
     Error *err = NULL;
@@ -44,8 +45,9 @@ void hmp_qom_list(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_qom_set(Monitor *mon, const QDict *qdict)
+void hmp_qom_set(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const bool json = qdict_get_try_bool(qdict, "json", false);
     const char *path = qdict_get_str(qdict, "path");
     const char *property = qdict_get_str(qdict, "property");
@@ -72,8 +74,9 @@ void hmp_qom_set(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_qom_get(Monitor *mon, const QDict *qdict)
+void hmp_qom_get(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *path = qdict_get_str(qdict, "path");
     const char *property = qdict_get_str(qdict, "property");
     Error *err = NULL;
@@ -132,8 +135,9 @@ static void print_qom_composition(Monitor *mon, Object *obj, int indent)
     g_array_free(children, TRUE);
 }
 
-void hmp_info_qom_tree(Monitor *mon, const QDict *dict)
+void hmp_info_qom_tree(MonitorHMP *hmp, const QDict *dict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *path = qdict_get_try_str(dict, "path");
     Object *obj;
     bool ambiguous = false;
@@ -154,8 +158,9 @@ void hmp_info_qom_tree(Monitor *mon, const QDict *dict)
     print_qom_composition(mon, obj, 0);
 }
 
-void hmp_object_add(Monitor *mon, const QDict *qdict)
+void hmp_object_add(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *options = qdict_get_str(qdict, "object");
     Error *err = NULL;
 
@@ -163,8 +168,9 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_object_del(Monitor *mon, const QDict *qdict)
+void hmp_object_del(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *id = qdict_get_str(qdict, "id");
     Error *err = NULL;
 
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
index 7b904a141654..ef69d23ff507 100644
--- a/replay/replay-debugging.c
+++ b/replay/replay-debugging.c
@@ -31,8 +31,9 @@ bool replay_running_debug(void)
     return replay_is_debugging;
 }
 
-void hmp_info_replay(Monitor *mon, const QDict *qdict)
+void hmp_info_replay(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     if (replay_mode == REPLAY_MODE_NONE) {
         monitor_printf(mon, "Record/replay is not active\n");
     } else {
@@ -103,7 +104,7 @@ void qmp_replay_break(int64_t icount, Error **errp)
     }
 }
 
-void hmp_replay_break(Monitor *mon, const QDict *qdict)
+void hmp_replay_break(MonitorHMP *hmp, const QDict *qdict)
 {
     int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
     Error *err = NULL;
@@ -124,7 +125,7 @@ void qmp_replay_delete_break(Error **errp)
     }
 }
 
-void hmp_replay_delete_break(Monitor *mon, const QDict *qdict)
+void hmp_replay_delete_break(MonitorHMP *hmp, const QDict *qdict)
 {
     Error *err = NULL;
 
@@ -209,7 +210,7 @@ void qmp_replay_seek(int64_t icount, Error **errp)
     replay_seek(icount, replay_stop_vm, errp);
 }
 
-void hmp_replay_seek(Monitor *mon, const QDict *qdict)
+void hmp_replay_seek(MonitorHMP *hmp, const QDict *qdict)
 {
     int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
     Error *err = NULL;
diff --git a/replay/stubs-system.c b/replay/stubs-system.c
index f8e17dcf1ce9..15e7411591ab 100644
--- a/replay/stubs-system.c
+++ b/replay/stubs-system.c
@@ -63,19 +63,19 @@ void replay_vmstate_init(void)
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 
-void hmp_info_replay(Monitor *mon, const QDict *qdict)
+void hmp_info_replay(MonitorHMP *hmp, const QDict *qdict)
 {
     error_report("replay support not available");
 }
-void hmp_replay_break(Monitor *mon, const QDict *qdict)
+void hmp_replay_break(MonitorHMP *hmp, const QDict *qdict)
 {
     error_report("replay support not available");
 }
-void hmp_replay_delete_break(Monitor *mon, const QDict *qdict)
+void hmp_replay_delete_break(MonitorHMP *hmp, const QDict *qdict)
 {
     error_report("replay support not available");
 }
-void hmp_replay_seek(Monitor *mon, const QDict *qdict)
+void hmp_replay_seek(MonitorHMP *hmp, const QDict *qdict)
 {
     error_report("replay support not available");
 }
diff --git a/stats/stats-hmp-cmds.c b/stats/stats-hmp-cmds.c
index b93b471b1b25..f280ad8c4314 100644
--- a/stats/stats-hmp-cmds.c
+++ b/stats/stats-hmp-cmds.c
@@ -187,8 +187,9 @@ static StatsFilter *stats_filter(StatsTarget target, const char *names,
     return filter;
 }
 
-void hmp_info_stats(Monitor *mon, const QDict *qdict)
+void hmp_info_stats(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *target_str = qdict_get_str(qdict, "target");
     const char *provider_str = qdict_get_try_str(qdict, "provider");
     const char *names = qdict_get_try_str(qdict, "names");
diff --git a/stubs/hmp-cmd-info_sev.c b/stubs/hmp-cmd-info_sev.c
index f3624423a334..6f2b87d1ad10 100644
--- a/stubs/hmp-cmd-info_sev.c
+++ b/stubs/hmp-cmd-info_sev.c
@@ -10,7 +10,8 @@
 #include "monitor/hmp.h"
 #include "monitor/monitor.h"
 
-void hmp_info_sev(Monitor *mon, const QDict *qdict)
+void hmp_info_sev(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     monitor_printf(mon, "SEV is not available in this QEMU\n");
 }
diff --git a/system/dirtylimit-hmp-cmds.c b/system/dirtylimit-hmp-cmds.c
index 4928d57cc8e3..4c100783778f 100644
--- a/system/dirtylimit-hmp-cmds.c
+++ b/system/dirtylimit-hmp-cmds.c
@@ -15,8 +15,9 @@
 #include "monitor/monitor.h"
 #include "system/dirtylimit.h"
 
-void hmp_cancel_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
+void hmp_cancel_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     int64_t cpu_index = qdict_get_try_int(qdict, "cpu_index", -1);
     Error *err = NULL;
 
@@ -30,8 +31,9 @@ void hmp_cancel_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
                    "dirty limit for virtual CPU]\n");
 }
 
-void hmp_set_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
+void hmp_set_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     int64_t dirty_rate = qdict_get_int(qdict, "dirty_rate");
     int64_t cpu_index = qdict_get_try_int(qdict, "cpu_index", -1);
     Error *err = NULL;
@@ -47,8 +49,9 @@ out:
     hmp_handle_error(mon, err);
 }
 
-void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
+void hmp_info_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     DirtyLimitInfoList *info;
     g_autoptr(DirtyLimitInfoList) head = NULL;
     Error *err = NULL;
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index 00fed791cce1..e27b9724867a 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -851,8 +851,9 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent, bool details)
 }
 #undef qdev_printf
 
-void hmp_info_qtree(Monitor *mon, const QDict *qdict)
+void hmp_info_qtree(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     bool details = !qdict_get_try_bool(qdict, "brief", false);
 
     if (sysbus_get_default()) {
@@ -860,7 +861,7 @@ void hmp_info_qtree(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_info_qdm(Monitor *mon, const QDict *qdict)
+void hmp_info_qdm(MonitorHMP *hmp, const QDict *qdict)
 {
     qdev_print_devinfos(true);
 }
@@ -1001,8 +1002,9 @@ void qmp_device_sync_config(const char *id, Error **errp)
     qdev_sync_config(dev, errp);
 }
 
-void hmp_device_add(Monitor *mon, const QDict *qdict)
+void hmp_device_add(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     QemuOpts *opts;
     DeviceState *dev;
@@ -1035,8 +1037,9 @@ out:
     hmp_handle_error(mon, err);
 }
 
-void hmp_device_del(Monitor *mon, const QDict *qdict)
+void hmp_device_del(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *id = qdict_get_str(qdict, "id");
     Error *err = NULL;
 
diff --git a/system/runstate-hmp-cmds.c b/system/runstate-hmp-cmds.c
index 02d1d42bf392..834b95835339 100644
--- a/system/runstate-hmp-cmds.c
+++ b/system/runstate-hmp-cmds.c
@@ -23,8 +23,9 @@
 #include "qobject/qdict.h"
 #include "qemu/accel.h"
 
-void hmp_info_status(Monitor *mon, const QDict *qdict)
+void hmp_info_status(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     StatusInfo *info;
 
     info = qmp_query_status(NULL);
@@ -41,8 +42,9 @@ void hmp_info_status(Monitor *mon, const QDict *qdict)
     qapi_free_StatusInfo(info);
 }
 
-void hmp_one_insn_per_tb(Monitor *mon, const QDict *qdict)
+void hmp_one_insn_per_tb(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *option = qdict_get_try_str(qdict, "option");
     AccelState *accel = current_accel();
     bool newval;
@@ -66,8 +68,9 @@ void hmp_one_insn_per_tb(Monitor *mon, const QDict *qdict)
                              newval, &error_abort);
 }
 
-void hmp_watchdog_action(Monitor *mon, const QDict *qdict)
+void hmp_watchdog_action(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     WatchdogAction action;
     char *qapi_value;
diff --git a/system/tpm-hmp-cmds.c b/system/tpm-hmp-cmds.c
index 9ed6ad6c4d46..094c3f16cf50 100644
--- a/system/tpm-hmp-cmds.c
+++ b/system/tpm-hmp-cmds.c
@@ -11,8 +11,9 @@
 #include "monitor/hmp.h"
 #include "qapi/error.h"
 
-void hmp_info_tpm(Monitor *mon, const QDict *qdict)
+void hmp_info_tpm(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
 #ifdef CONFIG_TPM
     TPMInfoList *info_list, *info;
     Error *err = NULL;
diff --git a/target/i386/cpu-apic.c b/target/i386/cpu-apic.c
index 04b7257ad120..2cb3147837d1 100644
--- a/target/i386/cpu-apic.c
+++ b/target/i386/cpu-apic.c
@@ -80,8 +80,9 @@ void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
      }
 }
 
-void hmp_info_local_apic(Monitor *mon, const QDict *qdict)
+void hmp_info_local_apic(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     CPUState *cs;
 
     if (qdict_haskey(qdict, "apic-id")) {
diff --git a/target/i386/monitor.c b/target/i386/monitor.c
index 9ed772e6d7f2..f1d2a327ddad 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -209,8 +209,9 @@ static void tlb_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
 }
 #endif /* TARGET_X86_64 */
 
-void hmp_info_tlb(Monitor *mon, const QDict *qdict)
+void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     CPUArchState *env;
     AddressSpace *as;
 
@@ -535,8 +536,9 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
 }
 #endif /* TARGET_X86_64 */
 
-void hmp_info_mem(Monitor *mon, const QDict *qdict)
+void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     CPUArchState *env;
     AddressSpace *as;
 
@@ -569,8 +571,9 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
     }
 }
 
-void hmp_mce(Monitor *mon, const QDict *qdict)
+void hmp_mce(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     X86CPU *cpu;
     CPUState *cs;
     int cpu_index = qdict_get_int(qdict, "cpu_index");
diff --git a/target/i386/sev.c b/target/i386/sev.c
index d7dcefc8ecf5..4473d02981ff 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -754,8 +754,9 @@ SevInfo *qmp_query_sev(Error **errp)
     return info;
 }
 
-void hmp_info_sev(Monitor *mon, const QDict *qdict)
+void hmp_info_sev(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     SevInfo *info = sev_get_info();
 
     if (!info || !info->enabled) {
diff --git a/target/m68k/monitor.c b/target/m68k/monitor.c
index 3e0df40a6b8b..0414474f2ffb 100644
--- a/target/m68k/monitor.c
+++ b/target/m68k/monitor.c
@@ -10,8 +10,9 @@
 #include "monitor/hmp.h"
 #include "monitor/monitor.h"
 
-void hmp_info_tlb(Monitor *mon, const QDict *qdict)
+void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     CPUArchState *env1 = mon_get_cpu_env(mon);
 
     if (!env1) {
diff --git a/target/ppc/monitor.c b/target/ppc/monitor.c
index 7c88e0e2bda0..99eda7351877 100644
--- a/target/ppc/monitor.c
+++ b/target/ppc/monitor.c
@@ -11,8 +11,9 @@
 #include "monitor/hmp.h"
 #include "cpu.h"
 
-void hmp_info_tlb(Monitor *mon, const QDict *qdict)
+void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     CPUArchState *env1 = mon_get_cpu_env(mon);
 
     if (!env1) {
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
index f8042db9cdf3..496d519c978d 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -215,8 +215,9 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
               last_paddr + last_size - pbase, last_attr);
 }
 
-void hmp_info_mem(Monitor *mon, const QDict *qdict)
+void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     CPUArchState *env;
 
     env = mon_get_cpu_env(mon);
diff --git a/target/sh4/monitor.c b/target/sh4/monitor.c
index 50324d3600c4..50da650b2e04 100644
--- a/target/sh4/monitor.c
+++ b/target/sh4/monitor.c
@@ -38,8 +38,9 @@ static void print_tlb(Monitor *mon, int idx, tlb_t *tlb)
                    tlb->d, tlb->wt);
 }
 
-void hmp_info_tlb(Monitor *mon, const QDict *qdict)
+void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     CPUArchState *env = mon_get_cpu_env(mon);
     int i;
 
diff --git a/target/sparc/monitor.c b/target/sparc/monitor.c
index 36f3d8d58e9d..09a15b821a1a 100644
--- a/target/sparc/monitor.c
+++ b/target/sparc/monitor.c
@@ -27,8 +27,9 @@
 #include "monitor/hmp.h"
 
 
-void hmp_info_tlb(Monitor *mon, const QDict *qdict)
+void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     CPUArchState *env1 = mon_get_cpu_env(mon);
 
     if (!env1) {
diff --git a/target/xtensa/monitor.c b/target/xtensa/monitor.c
index 2af84934f83d..a1082c44e11c 100644
--- a/target/xtensa/monitor.c
+++ b/target/xtensa/monitor.c
@@ -26,8 +26,9 @@
 #include "monitor/monitor.h"
 #include "monitor/hmp.h"
 
-void hmp_info_tlb(Monitor *mon, const QDict *qdict)
+void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     CPUArchState *env1 = mon_get_cpu_env(mon);
 
     if (!env1) {
diff --git a/trace/trace-hmp-cmds.c b/trace/trace-hmp-cmds.c
index c8f0133abecf..5a8158f4f4b6 100644
--- a/trace/trace-hmp-cmds.c
+++ b/trace/trace-hmp-cmds.c
@@ -33,7 +33,7 @@
 #include "trace/simple.h"
 #endif
 
-void hmp_trace_event(Monitor *mon, const QDict *qdict)
+void hmp_trace_event(MonitorHMP *hmp, const QDict *qdict)
 {
     const char *tp_name = qdict_get_str(qdict, "name");
     bool new_state = qdict_get_bool(qdict, "option");
@@ -47,8 +47,9 @@ void hmp_trace_event(Monitor *mon, const QDict *qdict)
 }
 
 #ifdef CONFIG_TRACE_SIMPLE
-void hmp_trace_file(Monitor *mon, const QDict *qdict)
+void hmp_trace_file(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *op = qdict_get_try_str(qdict, "op");
     const char *arg = qdict_get_try_str(qdict, "arg");
 
@@ -71,8 +72,9 @@ void hmp_trace_file(Monitor *mon, const QDict *qdict)
 }
 #endif
 
-void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
+void hmp_info_trace_events(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *name = qdict_get_try_str(qdict, "name");
     TraceEventInfoList *events;
     TraceEventInfoList *elem;
diff --git a/ui/ui-hmp-cmds.c b/ui/ui-hmp-cmds.c
index 4ef459490ba2..5f3522943c56 100644
--- a/ui/ui-hmp-cmds.c
+++ b/ui/ui-hmp-cmds.c
@@ -29,7 +29,7 @@
 
 static int mouse_button_state;
 
-void hmp_mouse_move(Monitor *mon, const QDict *qdict)
+void hmp_mouse_move(MonitorHMP *hmp, const QDict *qdict)
 {
     int dx, dy, dz, button;
     const char *dx_str = qdict_get_str(qdict, "dx_str");
@@ -53,7 +53,7 @@ void hmp_mouse_move(Monitor *mon, const QDict *qdict)
     qemu_input_event_sync();
 }
 
-void hmp_mouse_button(Monitor *mon, const QDict *qdict)
+void hmp_mouse_button(MonitorHMP *hmp, const QDict *qdict)
 {
     /* HMP mouse_button bitmask: 1=L, 2=R, 4=M */
     static uint32_t bmap[INPUT_BUTTON__MAX] = {
@@ -71,16 +71,18 @@ void hmp_mouse_button(Monitor *mon, const QDict *qdict)
     mouse_button_state = button_state;
 }
 
-void hmp_mouse_set(Monitor *mon, const QDict *qdict)
+void hmp_mouse_set(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qemu_mouse_set(qdict_get_int(qdict, "index"), &err);
     hmp_handle_error(mon, err);
 }
 
-void hmp_info_mice(Monitor *mon, const QDict *qdict)
+void hmp_info_mice(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     MouseInfoList *mice_list, *mouse;
 
     mice_list = qmp_query_mice(NULL);
@@ -148,8 +150,9 @@ static void hmp_info_vnc_servers(Monitor *mon, VncServerInfo2List *server)
     }
 }
 
-void hmp_info_vnc(Monitor *mon, const QDict *qdict)
+void hmp_info_vnc(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     VncInfo2List *info2l, *info2l_head;
     Error *err = NULL;
 
@@ -189,8 +192,9 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict)
 #endif
 
 #ifdef CONFIG_SPICE
-void hmp_info_spice(Monitor *mon, const QDict *qdict)
+void hmp_info_spice(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     SpiceChannelList *chan;
     SpiceInfo *info;
     const char *channel_name;
@@ -260,8 +264,9 @@ out:
 }
 #endif
 
-void hmp_set_password(Monitor *mon, const QDict *qdict)
+void hmp_set_password(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *protocol  = qdict_get_str(qdict, "protocol");
     const char *password  = qdict_get_str(qdict, "password");
     const char *display = qdict_get_try_str(qdict, "display");
@@ -295,8 +300,9 @@ out:
     hmp_handle_error(mon, err);
 }
 
-void hmp_expire_password(Monitor *mon, const QDict *qdict)
+void hmp_expire_password(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *protocol  = qdict_get_str(qdict, "protocol");
     const char *whenstr = qdict_get_str(qdict, "time");
     const char *display = qdict_get_try_str(qdict, "display");
@@ -366,8 +372,9 @@ static int index_from_key(const char *key, size_t key_length)
     return i;
 }
 
-void hmp_sendkey(Monitor *mon, const QDict *qdict)
+void hmp_sendkey(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *keys = qdict_get_str(qdict, "keys");
     KeyValue *v = NULL;
     KeyValueList *head = NULL, **tail = &head;
@@ -456,8 +463,9 @@ void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
 
 #ifdef CONFIG_PIXMAN
 void coroutine_fn
-hmp_screendump(Monitor *mon, const QDict *qdict)
+hmp_screendump(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     const char *filename = qdict_get_str(qdict, "filename");
     const char *id = qdict_get_try_str(qdict, "device");
     int64_t head = qdict_get_try_int(qdict, "head", 0);
@@ -478,8 +486,9 @@ end:
 }
 #endif
 
-void hmp_client_migrate_info(Monitor *mon, const QDict *qdict)
+void hmp_client_migrate_info(MonitorHMP *hmp, const QDict *qdict)
 {
+    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *protocol = qdict_get_str(qdict, "protocol");
     const char *hostname = qdict_get_str(qdict, "hostname");

-- 
2.55.0.543.g5ebe2ebe4ea8


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

* [PATCH v3 32/49] monitor: make hmp_handle_error() take MonitorHMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (30 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 31/49] monitor: change HMPCommand cmd to take MonitorHMP Marc-André Lureau
@ 2026-08-16 19:12 ` Marc-André Lureau
  2026-08-17  0:36   ` Dr. David Alan Gilbert
  2026-08-16 19:13 ` [PATCH v3 33/49] monitor: add monitor_cur_hmp() helper Marc-André Lureau
                   ` (16 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Kevin Wolf,
	Hanna Reitz, Paolo Bonzini, Ani Sinha, David Woodhouse,
	Paul Durrant, Richard Henderson, Michael S. Tsirkin,
	Mark Cave-Ayland, Jiri Pirko, Jason Wang, Gerd Hoffmann,
	Dr. David Alan Gilbert, Hyman Huang, Peter Xu, Fabiano Rosas,
	Zhao Liu, qemu-block, qemu-ppc

Mostly mechanical, with a few adjustments around it.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 block/monitor/block-hmp-cmds.c  | 73 +++++++++++++++--------------------------
 chardev/char-hmp-cmds.c         | 17 ++++------
 dump/dump-hmp-cmds.c            |  5 ++-
 hw/core/machine-hmp-cmds.c      | 26 +++++++--------
 hw/i386/kvm/xen_evtchn.c        |  4 +--
 hw/misc/mos6522.c               |  2 +-
 hw/net/rocker/rocker-hmp-cmds.c |  8 ++---
 hw/pci/pci-hmp-cmds.c           |  2 +-
 hw/uefi/ovmf-log.c              |  2 +-
 hw/virtio/virtio-hmp-cmds.c     | 10 +++---
 include/monitor/hmp.h           |  2 +-
 migration/dirtyrate.c           |  2 +-
 migration/migration-hmp-cmds.c  | 37 ++++++++-------------
 monitor/hmp-cmds.c              | 23 +++++--------
 monitor/hmp.c                   | 12 +++----
 net/net-hmp-cmds.c              | 11 +++----
 qom/qom-hmp-cmds.c              | 13 +++-----
 system/dirtylimit-hmp-cmds.c    |  7 ++--
 system/qdev-monitor.c           |  6 ++--
 system/runstate-hmp-cmds.c      |  3 +-
 target/i386/monitor.c           |  3 +-
 ui/ui-hmp-cmds.c                | 19 ++++-------
 22 files changed, 112 insertions(+), 175 deletions(-)

diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index 3914b5189d56..a2666e2f1b9b 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -57,7 +57,7 @@
 #include "block/block_int.h"
 #include "block/block-hmp-cmds.h"
 
-static void hmp_drive_add_node(Monitor *mon, const char *optstr)
+static void hmp_drive_add_node(MonitorHMP *hmp, const char *optstr)
 {
     QemuOpts *opts;
     QDict *qdict;
@@ -84,7 +84,7 @@ static void hmp_drive_add_node(Monitor *mon, const char *optstr)
     bdrv_set_monitor_owned(bs);
 out:
     qemu_opts_del(opts);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_drive_add(MonitorHMP *hmp, const QDict *qdict)
@@ -98,7 +98,7 @@ void hmp_drive_add(MonitorHMP *hmp, const QDict *qdict)
     bool node = qdict_get_try_bool(qdict, "node", false);
 
     if (node) {
-        hmp_drive_add_node(mon, optstr);
+        hmp_drive_add_node(hmp, optstr);
         return;
     }
 
@@ -133,12 +133,11 @@ err:
         monitor_remove_blk(blk);
         blk_unref(blk);
     }
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_drive_del(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *id = qdict_get_str(qdict, "id");
     BlockBackend *blk;
     BlockDriverState *bs;
@@ -193,12 +192,11 @@ void hmp_drive_del(MonitorHMP *hmp, const QDict *qdict)
 
 unlock:
     bdrv_graph_rdunlock_main_loop();
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_commit(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     BlockBackend *blk;
     int ret;
@@ -232,12 +230,11 @@ void hmp_commit(MonitorHMP *hmp, const QDict *qdict)
     }
 
 end:
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_drive_mirror(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *filename = qdict_get_str(qdict, "target");
     const char *format = qdict_get_try_str(qdict, "format");
     bool reuse = qdict_get_try_bool(qdict, "reuse", false);
@@ -259,12 +256,11 @@ void hmp_drive_mirror(MonitorHMP *hmp, const QDict *qdict)
     }
     qmp_drive_mirror(&mirror, &err);
 end:
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_drive_backup(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     const char *filename = qdict_get_str(qdict, "target");
     const char *format = qdict_get_try_str(qdict, "format");
@@ -290,69 +286,63 @@ void hmp_drive_backup(MonitorHMP *hmp, const QDict *qdict)
 
     qmp_drive_backup(&backup, &err);
 end:
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_block_job_set_speed(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
     int64_t value = qdict_get_int(qdict, "speed");
 
     qmp_block_job_set_speed(device, value, &error);
 
-    hmp_handle_error(mon, error);
+    hmp_handle_error(hmp, error);
 }
 
 void hmp_block_job_cancel(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
     bool force = qdict_get_try_bool(qdict, "force", false);
 
     qmp_block_job_cancel(device, true, force, &error);
 
-    hmp_handle_error(mon, error);
+    hmp_handle_error(hmp, error);
 }
 
 void hmp_block_job_pause(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
 
     qmp_block_job_pause(device, &error);
 
-    hmp_handle_error(mon, error);
+    hmp_handle_error(hmp, error);
 }
 
 void hmp_block_job_resume(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
 
     qmp_block_job_resume(device, &error);
 
-    hmp_handle_error(mon, error);
+    hmp_handle_error(hmp, error);
 }
 
 void hmp_block_job_complete(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
 
     qmp_block_job_complete(device, &error);
 
-    hmp_handle_error(mon, error);
+    hmp_handle_error(hmp, error);
 }
 
 void hmp_snapshot_blkdev(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     const char *filename = qdict_get_str(qdict, "snapshot-file");
     const char *format = qdict_get_try_str(qdict, "format");
@@ -363,35 +353,32 @@ void hmp_snapshot_blkdev(MonitorHMP *hmp, const QDict *qdict)
     mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
     qmp_blockdev_snapshot_sync(device, NULL, filename, NULL, format,
                                true, mode, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_snapshot_blkdev_internal(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     const char *name = qdict_get_str(qdict, "name");
     Error *err = NULL;
 
     qmp_blockdev_snapshot_internal_sync(device, name, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_snapshot_delete_blkdev_internal(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     const char *name = qdict_get_str(qdict, "name");
     const char *id = qdict_get_try_str(qdict, "id");
     Error *err = NULL;
 
     qmp_blockdev_snapshot_delete_internal_sync(device, id, name, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_nbd_server_start(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *uri = qdict_get_str(qdict, "uri");
     bool writable = qdict_get_try_bool(qdict, "writable", false);
     bool all = qdict_get_try_bool(qdict, "all", false);
@@ -449,12 +436,11 @@ void hmp_nbd_server_start(MonitorHMP *hmp, const QDict *qdict)
     qapi_free_BlockInfoList(block_list);
 
 exit:
-    hmp_handle_error(mon, local_err);
+    hmp_handle_error(hmp, local_err);
 }
 
 void hmp_nbd_server_add(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     const char *name = qdict_get_try_str(qdict, "name");
     bool writable = qdict_get_try_bool(qdict, "writable", false);
@@ -468,44 +454,40 @@ void hmp_nbd_server_add(MonitorHMP *hmp, const QDict *qdict)
     };
 
     qmp_nbd_server_add(&export, &local_err);
-    hmp_handle_error(mon, local_err);
+    hmp_handle_error(hmp, local_err);
 }
 
 void hmp_nbd_server_remove(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *name = qdict_get_str(qdict, "name");
     bool force = qdict_get_try_bool(qdict, "force", false);
     Error *err = NULL;
 
     /* Rely on BLOCK_EXPORT_REMOVE_MODE_SAFE being the default */
     qmp_nbd_server_remove(name, force, BLOCK_EXPORT_REMOVE_MODE_HARD, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_nbd_server_stop(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_nbd_server_stop(&err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void coroutine_fn hmp_block_resize(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     int64_t size = qdict_get_int(qdict, "size");
     Error *err = NULL;
 
     qmp_block_resize(device, NULL, size, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_block_stream(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
     const char *base = qdict_get_try_str(qdict, "base");
@@ -516,12 +498,11 @@ void hmp_block_stream(MonitorHMP *hmp, const QDict *qdict)
                      true, BLOCKDEV_ON_ERROR_REPORT, NULL,
                      false, false, false, false, &error);
 
-    hmp_handle_error(mon, error);
+    hmp_handle_error(hmp, error);
 }
 
 void hmp_block_set_io_throttle(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     char *device = (char *) qdict_get_str(qdict, "device");
     BlockIOThrottle throttle = {
@@ -545,23 +526,21 @@ void hmp_block_set_io_throttle(MonitorHMP *hmp, const QDict *qdict)
     }
 
     qmp_block_set_io_throttle(&throttle, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_eject(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     bool force = qdict_get_try_bool(qdict, "force", false);
     const char *device = qdict_get_str(qdict, "device");
     Error *err = NULL;
 
     qmp_eject(device, NULL, true, force, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_qemu_io(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     bool qdev = qdict_get_try_bool(qdict, "qdev", false);
     const char *device = qdict_get_str(qdict, "device");
     const char *command = qdict_get_str(qdict, "command");
@@ -570,7 +549,7 @@ void hmp_qemu_io(MonitorHMP *hmp, const QDict *qdict)
     qmp_x_qemu_io(qdev ? NULL : device,
                   qdev ? device : NULL,
                   command, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 static void print_block_info(Monitor *mon, BlockInfo *info,
@@ -851,7 +830,7 @@ void hmp_info_snapshots(MonitorHMP *hmp, const QDict *qdict)
 
     bs = bdrv_all_find_vmstate_bs(NULL, false, NULL, &err);
     if (!bs) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
 
diff --git a/chardev/char-hmp-cmds.c b/chardev/char-hmp-cmds.c
index d4a5a3a255a5..71017fd2d19e 100644
--- a/chardev/char-hmp-cmds.c
+++ b/chardev/char-hmp-cmds.c
@@ -40,14 +40,13 @@ void hmp_info_chardev(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_ringbuf_write(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *chardev = qdict_get_str(qdict, "device");
     const char *data = qdict_get_str(qdict, "data");
     Error *err = NULL;
 
     qmp_ringbuf_write(chardev, data, false, 0, &err);
 
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_ringbuf_read(MonitorHMP *hmp, const QDict *qdict)
@@ -60,7 +59,7 @@ void hmp_ringbuf_read(MonitorHMP *hmp, const QDict *qdict)
     int i;
 
     data = qmp_ringbuf_read(chardev, size, false, 0, &err);
-    if (hmp_handle_error(mon, err)) {
+    if (hmp_handle_error(hmp, err)) {
         return;
     }
 
@@ -82,7 +81,6 @@ void hmp_ringbuf_read(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_chardev_add(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *args = qdict_get_str(qdict, "args");
     Error *err = NULL;
     QemuOpts *opts;
@@ -94,12 +92,11 @@ void hmp_chardev_add(MonitorHMP *hmp, const QDict *qdict)
         qemu_chr_new_from_opts(opts, NULL, &err);
         qemu_opts_del(opts);
     }
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_chardev_change(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *args = qdict_get_str(qdict, "args");
     const char *id;
     Error *err = NULL;
@@ -129,25 +126,23 @@ end:
     qapi_free_ChardevReturn(ret);
     qapi_free_ChardevBackend(backend);
     qemu_opts_del(opts);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_chardev_remove(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *local_err = NULL;
 
     qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
-    hmp_handle_error(mon, local_err);
+    hmp_handle_error(hmp, local_err);
 }
 
 void hmp_chardev_send_break(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *local_err = NULL;
 
     qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err);
-    hmp_handle_error(mon, local_err);
+    hmp_handle_error(hmp, local_err);
 }
 
 void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str)
diff --git a/dump/dump-hmp-cmds.c b/dump/dump-hmp-cmds.c
index ba78ad026f1e..104ab5d2a53a 100644
--- a/dump/dump-hmp-cmds.c
+++ b/dump/dump-hmp-cmds.c
@@ -14,7 +14,6 @@
 
 void hmp_dump_guest_memory(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     bool win_dmp = qdict_get_try_bool(qdict, "windmp", false);
     bool paging = qdict_get_try_bool(qdict, "paging", false);
@@ -34,7 +33,7 @@ void hmp_dump_guest_memory(MonitorHMP *hmp, const QDict *qdict)
 
     if (zlib + lzo + snappy + win_dmp > 1) {
         error_setg(&err, "only one of '-z|-l|-s|-w' can be set");
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
 
@@ -80,7 +79,7 @@ void hmp_dump_guest_memory(MonitorHMP *hmp, const QDict *qdict)
 
     qmp_dump_guest_memory(paging, prot, true, detach, has_begin, begin,
                           has_length, length, true, dump_format, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
     g_free(prot);
 }
 
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
index 48fa27f12705..4e2f0c212b0d 100644
--- a/hw/core/machine-hmp-cmds.c
+++ b/hw/core/machine-hmp-cmds.c
@@ -57,7 +57,7 @@ void hmp_hotpluggable_cpus(MonitorHMP *hmp, const QDict *qdict)
     HotpluggableCPUList *saved = l;
     CpuInstanceProperties *c;
 
-    if (hmp_handle_error(mon, err)) {
+    if (hmp_handle_error(hmp, err)) {
         return;
     }
 
@@ -147,7 +147,7 @@ void hmp_info_memdev(MonitorHMP *hmp, const QDict *qdict)
     monitor_printf(mon, "\n");
 
     qapi_free_MemdevList(memdev_list);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_info_kvm(MonitorHMP *hmp, const QDict *qdict)
@@ -202,7 +202,7 @@ void hmp_info_balloon(MonitorHMP *hmp, const QDict *qdict)
     Error *err = NULL;
 
     info = qmp_query_balloon(&err);
-    if (hmp_handle_error(mon, err)) {
+    if (hmp_handle_error(hmp, err)) {
         return;
     }
 
@@ -236,47 +236,43 @@ void hmp_memsave(MonitorHMP *hmp, const QDict *qdict)
     }
 
     qmp_memsave(addr, size, filename, true, cpu_index, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_pmemsave(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     uint32_t size = qdict_get_int(qdict, "size");
     const char *filename = qdict_get_str(qdict, "filename");
     uint64_t addr = qdict_get_int(qdict, "val");
     Error *err = NULL;
 
     qmp_pmemsave(addr, size, filename, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_system_wakeup(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_system_wakeup(&err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_nmi(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_inject_nmi(&err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_balloon(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int64_t value = qdict_get_int(qdict, "value");
     Error *err = NULL;
 
     qmp_balloon(value, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_info_memory_devices(MonitorHMP *hmp, const QDict *qdict)
@@ -380,7 +376,7 @@ void hmp_info_memory_devices(MonitorHMP *hmp, const QDict *qdict)
     }
 
     qapi_free_MemoryDeviceInfoList(info_list);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_info_vm_generation_id(MonitorHMP *hmp, const QDict *qdict)
@@ -391,7 +387,7 @@ void hmp_info_vm_generation_id(MonitorHMP *hmp, const QDict *qdict)
     if (info) {
         monitor_printf(mon, "%s\n", info->guid);
     }
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
     qapi_free_GuidInfo(info);
 }
 
@@ -411,5 +407,5 @@ void hmp_info_memory_size_summary(MonitorHMP *hmp, const QDict *qdict)
 
         qapi_free_MemoryInfo(info);
     }
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c
index 845838c372d5..00dff6ee8760 100644
--- a/hw/i386/kvm/xen_evtchn.c
+++ b/hw/i386/kvm/xen_evtchn.c
@@ -2352,7 +2352,7 @@ void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict)
 
     info_list = qmp_xen_event_list(&err);
     if (err) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
 
@@ -2388,7 +2388,7 @@ void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict)
 
     qmp_xen_event_inject(port, &err);
     if (err) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
     } else {
         monitor_printf(mon, "Delivered port %d\n", port);
     }
diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index 15a6a1a75745..1c20c7582c34 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -592,7 +592,7 @@ void hmp_info_via(MonitorHMP *hmp, const QDict *qdict)
     Error *err = NULL;
     g_autoptr(HumanReadableText) info = qmp_x_query_via(&err);
 
-    if (hmp_handle_error(mon, err)) {
+    if (hmp_handle_error(hmp, err)) {
         return;
     }
     monitor_puts(mon, info->human_readable_text);
diff --git a/hw/net/rocker/rocker-hmp-cmds.c b/hw/net/rocker/rocker-hmp-cmds.c
index 856aaef5e210..6405ce26dd65 100644
--- a/hw/net/rocker/rocker-hmp-cmds.c
+++ b/hw/net/rocker/rocker-hmp-cmds.c
@@ -28,7 +28,7 @@ void hmp_rocker(MonitorHMP *hmp, const QDict *qdict)
     Error *err = NULL;
 
     rocker = qmp_query_rocker(name, &err);
-    if (hmp_handle_error(mon, err)) {
+    if (hmp_handle_error(hmp, err)) {
         return;
     }
 
@@ -47,7 +47,7 @@ void hmp_rocker_ports(MonitorHMP *hmp, const QDict *qdict)
     Error *err = NULL;
 
     list = qmp_query_rocker_ports(name, &err);
-    if (hmp_handle_error(mon, err)) {
+    if (hmp_handle_error(hmp, err)) {
         return;
     }
 
@@ -76,7 +76,7 @@ void hmp_rocker_of_dpa_flows(MonitorHMP *hmp, const QDict *qdict)
     Error *err = NULL;
 
     list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &err);
-    if (hmp_handle_error(mon, err)) {
+    if (hmp_handle_error(hmp, err)) {
         return;
     }
 
@@ -226,7 +226,7 @@ void hmp_rocker_of_dpa_groups(MonitorHMP *hmp, const QDict *qdict)
     Error *err = NULL;
 
     list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &err);
-    if (hmp_handle_error(mon, err)) {
+    if (hmp_handle_error(hmp, err)) {
         return;
     }
 
diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c
index be24aecc8ac8..51d95d76620e 100644
--- a/hw/pci/pci-hmp-cmds.c
+++ b/hw/pci/pci-hmp-cmds.c
@@ -247,5 +247,5 @@ void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict)
                    PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
 
 out:
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
diff --git a/hw/uefi/ovmf-log.c b/hw/uefi/ovmf-log.c
index c97622b2aad6..0d59a74ad60e 100644
--- a/hw/uefi/ovmf-log.c
+++ b/hw/uefi/ovmf-log.c
@@ -269,7 +269,7 @@ void hmp_info_firmware_log(MonitorHMP *hmp, const QDict *qdict)
     maxsize = qdict_get_try_int(qdict, "max-size", -1);
     log = qmp_query_firmware_log(maxsize != -1, (uint64_t)maxsize, &err);
     if (err)  {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
 
diff --git a/hw/virtio/virtio-hmp-cmds.c b/hw/virtio/virtio-hmp-cmds.c
index 49f3367785ba..fb36c8b9274c 100644
--- a/hw/virtio/virtio-hmp-cmds.c
+++ b/hw/virtio/virtio-hmp-cmds.c
@@ -88,7 +88,7 @@ void hmp_virtio_query(MonitorHMP *hmp, const QDict *qdict)
     VirtioInfoList *node;
 
     if (err != NULL) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
 
@@ -114,7 +114,7 @@ void hmp_virtio_status(MonitorHMP *hmp, const QDict *qdict)
     VirtioStatus *s = qmp_x_query_virtio_status(path, &err);
 
     if (err != NULL) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
 
@@ -195,7 +195,7 @@ void hmp_vhost_queue_status(MonitorHMP *hmp, const QDict *qdict)
         qmp_x_query_virtio_vhost_queue_status(path, queue, &err);
 
     if (err != NULL) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
 
@@ -228,7 +228,7 @@ void hmp_virtio_queue_status(MonitorHMP *hmp, const QDict *qdict)
     VirtQueueStatus *s = qmp_x_query_virtio_queue_status(path, queue, &err);
 
     if (err != NULL) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
 
@@ -278,7 +278,7 @@ void hmp_virtio_queue_element(MonitorHMP *hmp, const QDict *qdict)
     e = qmp_x_query_virtio_queue_element(path, queue, index != -1,
                                          index, &err);
     if (err != NULL) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
 
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index 7a270ad3f25c..827a56144824 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -54,7 +54,7 @@ void monitor_register_hmp_info_hrt(const char *name,
 CPUArchState *mon_get_cpu_env(Monitor *mon);
 CPUState *mon_get_cpu(Monitor *mon);
 
-bool hmp_handle_error(Monitor *mon, Error *err);
+bool hmp_handle_error(MonitorHMP *hmp, Error *err);
 void hmp_help_cmd(Monitor *mon, const char *name);
 strList *hmp_split_at_comma(const char *str);
 
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 567abab321cc..3c0931796ce2 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -926,7 +926,7 @@ void hmp_calc_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
                         true, mode,
                         &err);
     if (err) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
 
diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c
index 8d2e8735277e..73a974259478 100644
--- a/migration/migration-hmp-cmds.c
+++ b/migration/migration-hmp-cmds.c
@@ -478,7 +478,6 @@ void hmp_info_migrate_parameters(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_loadvm(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     RunState saved_state = runstate_get();
 
     const char *name = qdict_get_str(qdict, "name");
@@ -490,27 +489,25 @@ void hmp_loadvm(MonitorHMP *hmp, const QDict *qdict)
         load_snapshot_resume(saved_state);
     }
 
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_savevm(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     save_snapshot(qdict_get_try_str(qdict, "name"),
                   true, NULL, false, NULL, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_delvm(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *name = qdict_get_str(qdict, "name");
 
     delete_snapshot(name, false, NULL, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_migrate_cancel(MonitorHMP *hmp, const QDict *qdict)
@@ -520,7 +517,6 @@ void hmp_migrate_cancel(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_migrate_continue(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *state = qdict_get_str(qdict, "state");
     int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err);
@@ -529,12 +525,11 @@ void hmp_migrate_continue(MonitorHMP *hmp, const QDict *qdict)
         qmp_migrate_continue(val, &err);
     }
 
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_migrate_incoming(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *uri = qdict_get_str(qdict, "uri");
     MigrationChannelList *caps = NULL;
@@ -549,34 +544,31 @@ void hmp_migrate_incoming(MonitorHMP *hmp, const QDict *qdict)
     qapi_free_MigrationChannelList(caps);
 
 end:
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_migrate_recover(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *uri = qdict_get_str(qdict, "uri");
 
     qmp_migrate_recover(uri, &err);
 
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_migrate_pause(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_migrate_pause(&err);
 
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 
 void hmp_migrate_set_capability(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *cap = qdict_get_str(qdict, "capability");
     bool state = qdict_get_bool(qdict, "state");
     Error *err = NULL;
@@ -597,12 +589,11 @@ void hmp_migrate_set_capability(MonitorHMP *hmp, const QDict *qdict)
     qapi_free_MigrationCapabilityStatusList(caps);
 
 end:
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_migrate_set_parameter(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *param = qdict_get_str(qdict, "parameter");
     const char *valuestr = qdict_get_str(qdict, "value");
     Visitor *v = string_input_visitor_new(valuestr);
@@ -799,25 +790,23 @@ void hmp_migrate_set_parameter(MonitorHMP *hmp, const QDict *qdict)
  cleanup:
     qapi_free_MigrationParameters(p);
     visit_free(v);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_migrate_start_postcopy(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     qmp_migrate_start_postcopy(&err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 #ifdef CONFIG_REPLICATION
 void hmp_x_colo_lost_heartbeat(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_x_colo_lost_heartbeat(&err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 #endif
 
@@ -860,7 +849,7 @@ void hmp_migrate(MonitorHMP *hmp, const QDict *qdict)
     g_autoptr(MigrationChannel) channel_cpr = NULL;
 
     if (!migrate_uri_parse(uri, &channel, &err)) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
     QAPI_LIST_PREPEND(caps, g_steal_pointer(&channel));
@@ -882,7 +871,7 @@ void hmp_migrate(MonitorHMP *hmp, const QDict *qdict)
     }
 
     qmp_migrate(NULL, true, caps, true, resume, &err);
-    if (hmp_handle_error(mon, err)) {
+    if (hmp_handle_error(hmp, err)) {
         return;
     }
 
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index afe4817b4056..d1e7e4de6585 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -75,7 +75,7 @@ static void __attribute__((__constructor__)) sortcmdlist(void)
           compare_mon_cmd);
 }
 
-bool hmp_handle_error(Monitor *mon, Error *err)
+bool hmp_handle_error(MonitorHMP *hmp, Error *err)
 {
     if (err) {
         error_reportf_err(err, "Error: ");
@@ -165,17 +165,16 @@ void hmp_sync_profile(MonitorHMP *hmp, const QDict *qdict)
 
         error_setg(&err, "invalid parameter '%s',"
                    " expecting 'on', 'off', or 'reset'", op);
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
     }
 }
 
 void hmp_exit_preconfig(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_x_exit_preconfig(&err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_cpu(MonitorHMP *hmp, const QDict *qdict)
@@ -193,11 +192,10 @@ void hmp_cpu(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_cont(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qmp_cont(&err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_change(MonitorHMP *hmp, const QDict *qdict)
@@ -219,29 +217,27 @@ void hmp_change(MonitorHMP *hmp, const QDict *qdict)
         hmp_change_medium(mon, device, target, arg, read_only, force, &err);
     }
 
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 #ifdef CONFIG_POSIX
 void hmp_getfd(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *fdname = qdict_get_str(qdict, "fdname");
     Error *err = NULL;
 
     qmp_getfd(fdname, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 #endif
 
 void hmp_closefd(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *fdname = qdict_get_str(qdict, "fdname");
     Error *err = NULL;
 
     qmp_closefd(fdname, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_info_iothreads(MonitorHMP *hmp, const QDict *qdict)
@@ -502,17 +498,16 @@ void hmp_info_mtree(MonitorHMP *hmp, const QDict *qdict)
 #if defined(CONFIG_FDT)
 void hmp_dumpdtb(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *filename = qdict_get_str(qdict, "filename");
     Error *local_err = NULL;
 
     qmp_dumpdtb(filename, &local_err);
 
-    if (hmp_handle_error(mon, local_err)) {
+    if (hmp_handle_error(hmp, local_err)) {
         return;
     }
 
-    monitor_printf(mon, "DTB dumped to '%s'\n", filename);
+    monitor_printf(MONITOR(hmp), "DTB dumped to '%s'\n", filename);
 }
 #endif
 
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 6e6334b64685..57c4127641ac 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -1215,28 +1215,28 @@ fail:
     return NULL;
 }
 
-static void hmp_info_human_readable_text(Monitor *mon,
+static void hmp_info_human_readable_text(MonitorHMP *hmp,
                                          HumanReadableText *(*handler)(Error **))
 {
     Error *err = NULL;
     g_autoptr(HumanReadableText) info = handler(&err);
 
-    if (hmp_handle_error(mon, err)) {
+    if (hmp_handle_error(hmp, err)) {
         return;
     }
 
-    monitor_puts(mon, info->human_readable_text);
+    monitor_puts(MONITOR(hmp), info->human_readable_text);
 }
 
-static void handle_hmp_command_exec(MonitorHMP *mon,
+static void handle_hmp_command_exec(MonitorHMP *hmp,
                                     const HMPCommand *cmd,
                                     QDict *qdict)
 {
     if (cmd->cmd_info_hrt) {
-        hmp_info_human_readable_text(MONITOR(mon),
+        hmp_info_human_readable_text(hmp,
                                      cmd->cmd_info_hrt);
     } else {
-        cmd->cmd(mon, qdict);
+        cmd->cmd(hmp, qdict);
     }
 }
 
diff --git a/net/net-hmp-cmds.c b/net/net-hmp-cmds.c
index 702103b6a920..5b1c678f5d89 100644
--- a/net/net-hmp-cmds.c
+++ b/net/net-hmp-cmds.c
@@ -53,7 +53,7 @@ void hmp_info_network(MonitorHMP *hmp, const QDict *qdict)
     NetHubInfoList *h;
     NetworkClientInfoList *entry;
 
-    if (hmp_handle_error(mon, err)) {
+    if (hmp_handle_error(hmp, err)) {
         return;
     }
 
@@ -86,13 +86,12 @@ void hmp_info_network(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_set_link(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *name = qdict_get_str(qdict, "name");
     bool up = qdict_get_bool(qdict, "up");
     Error *err = NULL;
 
     qmp_set_link(name, up, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 
@@ -113,7 +112,6 @@ void hmp_announce_self(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_netdev_add(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     QemuOpts *opts;
     const char *type = qdict_get_try_str(qdict, "type");
@@ -133,17 +131,16 @@ void hmp_netdev_add(MonitorHMP *hmp, const QDict *qdict)
     }
 
 out:
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_netdev_del(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *id = qdict_get_str(qdict, "id");
     Error *err = NULL;
 
     qmp_netdev_del(id, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 
diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c
index 16847d1ce261..2e2eb33371e2 100644
--- a/qom/qom-hmp-cmds.c
+++ b/qom/qom-hmp-cmds.c
@@ -42,12 +42,11 @@ void hmp_qom_list(MonitorHMP *hmp, const QDict *qdict)
         }
         qapi_free_ObjectPropertyInfoList(start);
     }
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_qom_set(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const bool json = qdict_get_try_bool(qdict, "json", false);
     const char *path = qdict_get_str(qdict, "path");
     const char *property = qdict_get_str(qdict, "property");
@@ -71,7 +70,7 @@ void hmp_qom_set(MonitorHMP *hmp, const QDict *qdict)
         }
     }
 
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_qom_get(MonitorHMP *hmp, const QDict *qdict)
@@ -89,7 +88,7 @@ void hmp_qom_get(MonitorHMP *hmp, const QDict *qdict)
     }
 
     qobject_unref(obj);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 typedef struct QOMCompositionState {
@@ -160,22 +159,20 @@ void hmp_info_qom_tree(MonitorHMP *hmp, const QDict *dict)
 
 void hmp_object_add(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *options = qdict_get_str(qdict, "object");
     Error *err = NULL;
 
     user_creatable_add_from_str(options, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_object_del(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *id = qdict_get_str(qdict, "id");
     Error *err = NULL;
 
     user_creatable_del(id, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str)
diff --git a/system/dirtylimit-hmp-cmds.c b/system/dirtylimit-hmp-cmds.c
index 4c100783778f..75194add7931 100644
--- a/system/dirtylimit-hmp-cmds.c
+++ b/system/dirtylimit-hmp-cmds.c
@@ -23,7 +23,7 @@ void hmp_cancel_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
 
     qmp_cancel_vcpu_dirty_limit(!!(cpu_index != -1), cpu_index, &err);
     if (err) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
 
@@ -33,7 +33,6 @@ void hmp_cancel_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_set_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int64_t dirty_rate = qdict_get_int(qdict, "dirty_rate");
     int64_t cpu_index = qdict_get_try_int(qdict, "cpu_index", -1);
     Error *err = NULL;
@@ -46,7 +45,7 @@ void hmp_set_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
     qmp_set_vcpu_dirty_limit(!!(cpu_index != -1), cpu_index, dirty_rate, &err);
 
 out:
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_info_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
@@ -63,7 +62,7 @@ void hmp_info_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
 
     head = qmp_query_vcpu_dirty_limit(&err);
     if (err) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
 
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index e27b9724867a..5c2de2f53cc9 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -1004,7 +1004,6 @@ void qmp_device_sync_config(const char *id, Error **errp)
 
 void hmp_device_add(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     QemuOpts *opts;
     DeviceState *dev;
@@ -1034,17 +1033,16 @@ void hmp_device_add(MonitorHMP *hmp, const QDict *qdict)
     }
     object_unref(dev);
 out:
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_device_del(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *id = qdict_get_str(qdict, "id");
     Error *err = NULL;
 
     qmp_device_del(id, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
diff --git a/system/runstate-hmp-cmds.c b/system/runstate-hmp-cmds.c
index 834b95835339..051ee45ee74c 100644
--- a/system/runstate-hmp-cmds.c
+++ b/system/runstate-hmp-cmds.c
@@ -70,7 +70,6 @@ void hmp_one_insn_per_tb(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_watchdog_action(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     WatchdogAction action;
     char *qapi_value;
@@ -79,7 +78,7 @@ void hmp_watchdog_action(MonitorHMP *hmp, const QDict *qdict)
     action = qapi_enum_parse(&WatchdogAction_lookup, qapi_value, -1, &err);
     g_free(qapi_value);
     if (err) {
-        hmp_handle_error(mon, err);
+        hmp_handle_error(hmp, err);
         return;
     }
     qmp_watchdog_set_action(action, &error_abort);
diff --git a/target/i386/monitor.c b/target/i386/monitor.c
index f1d2a327ddad..f68dd38ac225 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -573,7 +573,6 @@ void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_mce(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     X86CPU *cpu;
     CPUState *cs;
     int cpu_index = qdict_get_int(qdict, "cpu_index");
@@ -596,5 +595,5 @@ void hmp_mce(MonitorHMP *hmp, const QDict *qdict)
     } else {
         error_setg(&err, "Invalid CPU %d", cpu_index);
     }
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
diff --git a/ui/ui-hmp-cmds.c b/ui/ui-hmp-cmds.c
index 5f3522943c56..186209fd0234 100644
--- a/ui/ui-hmp-cmds.c
+++ b/ui/ui-hmp-cmds.c
@@ -73,11 +73,10 @@ void hmp_mouse_button(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_mouse_set(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
 
     qemu_mouse_set(qdict_get_int(qdict, "index"), &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_info_mice(MonitorHMP *hmp, const QDict *qdict)
@@ -158,7 +157,7 @@ void hmp_info_vnc(MonitorHMP *hmp, const QDict *qdict)
 
     info2l = qmp_query_vnc_servers(&err);
     info2l_head = info2l;
-    if (hmp_handle_error(mon, err)) {
+    if (hmp_handle_error(hmp, err)) {
         return;
     }
     if (!info2l) {
@@ -266,7 +265,6 @@ out:
 
 void hmp_set_password(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *protocol  = qdict_get_str(qdict, "protocol");
     const char *password  = qdict_get_str(qdict, "password");
     const char *display = qdict_get_try_str(qdict, "display");
@@ -297,12 +295,11 @@ void hmp_set_password(MonitorHMP *hmp, const QDict *qdict)
     qmp_set_password(&opts, &err);
 
 out:
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 void hmp_expire_password(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *protocol  = qdict_get_str(qdict, "protocol");
     const char *whenstr = qdict_get_str(qdict, "time");
     const char *display = qdict_get_try_str(qdict, "display");
@@ -325,7 +322,7 @@ void hmp_expire_password(MonitorHMP *hmp, const QDict *qdict)
     qmp_expire_password(&opts, &err);
 
 out:
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 
 #ifdef CONFIG_VNC
@@ -427,7 +424,7 @@ void hmp_sendkey(MonitorHMP *hmp, const QDict *qdict)
     }
 
     qmp_send_key(head, has_hold_time, hold_time, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 
 out:
     qapi_free_KeyValue(v);
@@ -465,7 +462,6 @@ void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
 void coroutine_fn
 hmp_screendump(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *filename = qdict_get_str(qdict, "filename");
     const char *id = qdict_get_try_str(qdict, "device");
     int64_t head = qdict_get_try_int(qdict, "head", 0);
@@ -482,13 +478,12 @@ hmp_screendump(MonitorHMP *hmp, const QDict *qdict)
     qmp_screendump(filename, id, id != NULL, head,
                    input_format != NULL, format, &err);
 end:
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }
 #endif
 
 void hmp_client_migrate_info(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *protocol = qdict_get_str(qdict, "protocol");
     const char *hostname = qdict_get_str(qdict, "hostname");
@@ -501,5 +496,5 @@ void hmp_client_migrate_info(MonitorHMP *hmp, const QDict *qdict)
     qmp_client_migrate_info(protocol, hostname,
                             has_port, port, has_tls_port, tls_port,
                             cert_subject, &err);
-    hmp_handle_error(mon, err);
+    hmp_handle_error(hmp, err);
 }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 33/49] monitor: add monitor_cur_hmp() helper
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (31 preceding siblings ...)
  2026-08-16 19:12 ` [PATCH v3 32/49] monitor: make hmp_handle_error() " Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-17  0:49   ` Dr. David Alan Gilbert
  2026-08-16 19:13 ` [PATCH v3 34/49] qemu-print: switch to use monitor_cur_hmp() Marc-André Lureau
                   ` (15 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Dr. David Alan Gilbert, Paolo Bonzini

This will help to simplify the code in the following changes.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/monitor/hmp.h |  2 ++
 monitor/hmp.c         | 10 ++++++++++
 stubs/meson.build     |  1 +
 stubs/monitor-hmp.c   |  9 +++++++++
 4 files changed, 22 insertions(+)

diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index 827a56144824..6aa562ddbaa2 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -36,6 +36,8 @@ struct MonitorDef {
 void monitor_new_hmp(const char *id, const char *chardev_id,
                      bool use_readline, Error **errp);
 
+MonitorHMP *monitor_cur_hmp(void);
+
 int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
     G_GNUC_PRINTF(2, 0);
 int monitor_printf(Monitor *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 57c4127641ac..47fb7cef6de2 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -47,6 +47,16 @@
 
 OBJECT_DEFINE_TYPE(MonitorHMP, monitor_hmp, MONITOR_HMP, MONITOR);
 
+MonitorHMP *monitor_cur_hmp(void)
+{
+    Monitor *mon = monitor_cur();
+    if (mon) {
+        return (MonitorHMP *)object_dynamic_cast(OBJECT(mon),
+                                                 TYPE_MONITOR_HMP);
+    }
+    return NULL;
+}
+
 static void monitor_hmp_finalize(Object *obj)
 {
     MonitorHMP *hmp = MONITOR_HMP(obj);
diff --git a/stubs/meson.build b/stubs/meson.build
index 3b2f2680b193..7e15687a62b7 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -7,6 +7,7 @@ stub_ss.add(files('fdset.c'))
 stub_ss.add(files('iothread-lock.c'))
 stub_ss.add(files('is-daemonized.c'))
 stub_ss.add(files('monitor-core.c'))
+stub_ss.add(files('monitor-hmp.c'))
 stub_ss.add(files('replay-mode.c'))
 stub_ss.add(files('trace-control.c'))
 
diff --git a/stubs/monitor-hmp.c b/stubs/monitor-hmp.c
new file mode 100644
index 000000000000..9452a3f0c2c8
--- /dev/null
+++ b/stubs/monitor-hmp.c
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "monitor/hmp.h"
+
+MonitorHMP *monitor_cur_hmp(void)
+{
+    return NULL;
+}

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 34/49] qemu-print: switch to use monitor_cur_hmp()
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (32 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 33/49] monitor: add monitor_cur_hmp() helper Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-16 19:13 ` [PATCH v3 35/49] error-report: " Marc-André Lureau
                   ` (14 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Dr. David Alan Gilbert

Note that this fixes qemu_vprintf() (and thus qemu_printf) to do as said
in the code comment: print to current HMP if we have one, else to
stdout, instead of trying to print to the current monitor (which may not
actually have hmp-only print capability/callback and fail silently).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 util/qemu-print.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/util/qemu-print.c b/util/qemu-print.c
index a2d1f0244168..0eecc05b0330 100644
--- a/util/qemu-print.c
+++ b/util/qemu-print.c
@@ -21,9 +21,9 @@
  */
 int qemu_vprintf(const char *fmt, va_list ap)
 {
-    Monitor *cur_mon = monitor_cur();
-    if (cur_mon) {
-        return monitor_vprintf(cur_mon, fmt, ap);
+    MonitorHMP *hmp = monitor_cur_hmp();
+    if (hmp) {
+        return monitor_vprintf(MONITOR(hmp), fmt, ap);
     }
     return vprintf(fmt, ap);
 }
@@ -53,7 +53,8 @@ int qemu_printf(const char *fmt, ...)
 int qemu_vfprintf(FILE *stream, const char *fmt, va_list ap)
 {
     if (!stream) {
-        return monitor_vprintf(monitor_cur(), fmt, ap);
+        MonitorHMP *hmp = monitor_cur_hmp();
+        return hmp ? monitor_vprintf(MONITOR(hmp), fmt, ap) : -1;
     }
     return vfprintf(stream, fmt, ap);
 }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 35/49] error-report: switch to use monitor_cur_hmp()
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (33 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 34/49] qemu-print: switch to use monitor_cur_hmp() Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-16 19:13 ` [PATCH v3 36/49] monitor: tighten monitor_set_cpu()/get_cpu() Marc-André Lureau
                   ` (13 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster

Instead of passing a Monitor pointer through error_vprintf_mon() and
error_printf_mon(), call monitor_cur_hmp() directly. This removes the
monitor parameter from the internal helpers and the manual
object_dynamic_cast() in vreport().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 util/error-report.c | 72 +++++++++++++++++++++++++----------------------------
 1 file changed, 34 insertions(+), 38 deletions(-)

diff --git a/util/error-report.c b/util/error-report.c
index aaa15bc79827..70cbd174ffae 100644
--- a/util/error-report.c
+++ b/util/error-report.c
@@ -30,34 +30,31 @@ bool error_with_guestname;
 const char *error_guest_name;
 
 /*
- * Print to the current human monitor if we have one, else to stderr.
+ * Print to the current HMP monitor if we have one, else to stderr.
  */
-static int G_GNUC_PRINTF(2, 0)
-error_vprintf_mon(Monitor *cur_mon, const char *fmt, va_list ap)
+static int G_GNUC_PRINTF(1, 0)
+error_vprintf_mon(const char *fmt, va_list ap)
 {
-    /*
-     * This will return -1 if 'cur_mon' is NULL, or is QMP.
-     * IOW this will only print if in HMP, otherwise we
-     * fallback to stderr for QMP / no-monitor scenarios.
-     */
-    int ret = monitor_vprintf(cur_mon, fmt, ap);
-    if (ret == -1) {
-        ret = vfprintf(stderr, fmt, ap);
+    MonitorHMP *hmp = monitor_cur_hmp();
+
+    if (hmp) {
+        return monitor_vprintf(MONITOR(hmp), fmt, ap);
     }
-    return ret;
+
+    return vfprintf(stderr, fmt, ap);
 }
 
 /*
- * Print to the current human monitor if we have one, else to stderr.
+ * Print to the current HMP monitor if we have one, else to stderr.
  */
-static int G_GNUC_PRINTF(2, 3)
-error_printf_mon(Monitor *cur_mon, const char *fmt, ...)
+static int G_GNUC_PRINTF(1, 2)
+error_printf_mon(const char *fmt, ...)
 {
     va_list ap;
     int ret;
 
     va_start(ap, fmt);
-    ret = error_vprintf_mon(cur_mon, fmt, ap);
+    ret = error_vprintf_mon(fmt, ap);
     va_end(ap);
     return ret;
 }
@@ -67,7 +64,7 @@ error_printf_mon(Monitor *cur_mon, const char *fmt, ...)
  */
 int error_vprintf(const char *fmt, va_list ap)
 {
-    return error_vprintf_mon(monitor_cur(), fmt, ap);
+    return error_vprintf_mon(fmt, ap);
 }
 
 /*
@@ -79,7 +76,7 @@ int error_printf(const char *fmt, ...)
     int ret;
 
     va_start(ap, fmt);
-    ret = error_vprintf_mon(monitor_cur(), fmt, ap);
+    ret = error_vprintf_mon(fmt, ap);
     va_end(ap);
     return ret;
 }
@@ -183,13 +180,13 @@ void loc_set_file(const char *fname, int lno)
  * Print current location to current HMP monitor if we have one, else
  * to stderr.
  */
-static void print_loc(Monitor *cur)
+static void print_loc(MonitorHMP *hmp)
 {
     const char *sep = "";
     int i;
     const char *const *argp;
 
-    if (!cur && g_get_prgname()) {
+    if (!hmp && g_get_prgname()) {
         fprintf(stderr, "%s:", g_get_prgname());
         sep = " ";
     }
@@ -197,20 +194,20 @@ static void print_loc(Monitor *cur)
     case LOC_CMDLINE:
         argp = cur_loc->ptr;
         for (i = 0; i < cur_loc->num; i++) {
-            error_printf_mon(cur, "%s%s", sep, argp[i]);
+            error_printf_mon("%s%s", sep, argp[i]);
             sep = " ";
         }
-        error_printf_mon(cur, ": ");
+        error_printf_mon(": ");
         break;
     case LOC_FILE:
-        error_printf_mon(cur, "%s:", (const char *)cur_loc->ptr);
+        error_printf_mon("%s:", (const char *)cur_loc->ptr);
         if (cur_loc->num) {
-            error_printf_mon(cur, "%d:", cur_loc->num);
+            error_printf_mon("%d:", cur_loc->num);
         }
-        error_printf_mon(cur, " ");
+        error_printf_mon(" ");
         break;
     default:
-        error_printf_mon(cur, "%s", sep);
+        error_printf_mon("%s", sep);
     }
 }
 
@@ -233,45 +230,44 @@ static void vreport(report_type type, const char *fmt, va_list ap)
 {
     /*
      * When current monitor is QMP, messages must go to stderr
-     * and have prefixes added, so we cast to HMP, leaving 'cur'
+     * and have prefixes added, so we cast to HMP, leaving 'hmp'
      * as NULL in QMP case
      */
-    Monitor *cur = MONITOR(
-        object_dynamic_cast(OBJECT(monitor_cur()), TYPE_MONITOR_HMP));
+    MonitorHMP *hmp = monitor_cur_hmp();
     gchar *timestr;
 
-    if (!cur) {
+    if (!hmp) {
         qemu_flockfile(stderr);
     }
 
-    if (message_with_timestamp && !cur) {
+    if (message_with_timestamp && !hmp) {
         timestr = real_time_iso8601();
         fprintf(stderr, "%s ", timestr);
         g_free(timestr);
     }
 
     /* Only prepend guest name if -msg guest-name and -name guest=... are set */
-    if (error_with_guestname && error_guest_name && !cur) {
+    if (error_with_guestname && error_guest_name && !hmp) {
         fprintf(stderr, "%s ", error_guest_name);
     }
 
-    print_loc(cur);
+    print_loc(hmp);
 
     switch (type) {
     case REPORT_TYPE_ERROR:
         break;
     case REPORT_TYPE_WARNING:
-        error_printf_mon(cur, "warning: ");
+        error_printf_mon("warning: ");
         break;
     case REPORT_TYPE_INFO:
-        error_printf_mon(cur, "info: ");
+        error_printf_mon("info: ");
         break;
     }
 
-    error_vprintf_mon(cur, fmt, ap);
-    error_printf_mon(cur, "\n");
+    error_vprintf_mon(fmt, ap);
+    error_printf_mon("\n");
 
-    if (!cur) {
+    if (!hmp) {
         qemu_funlockfile(stderr);
     }
 }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 36/49] monitor: tighten monitor_set_cpu()/get_cpu()
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (34 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 35/49] error-report: " Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-18 14:15   ` Dr. David Alan Gilbert
  2026-08-16 19:13 ` [PATCH v3 37/49] monitor: tighten monitor_printf*() Marc-André Lureau
                   ` (12 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Dr. David Alan Gilbert, Paolo Bonzini, Zhao Liu, Laurent Vivier,
	Nicholas Piggin, Chinmay Rath, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Yoshinori Sato,
	Mark Cave-Ayland, Artyom Tarasenko, Max Filippov, qemu-ppc,
	qemu-riscv

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.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/core/machine-hmp-cmds.c |  4 ++--
 include/monitor/hmp.h      |  7 +++---
 include/monitor/monitor.h  |  1 -
 monitor/hmp-cmds.c         | 53 ++++++++++++++++++++++------------------------
 monitor/hmp.c              | 18 ++++++++--------
 monitor/monitor-internal.h |  2 +-
 monitor/qmp-cmds.c         |  2 +-
 stats/stats-hmp-cmds.c     |  2 +-
 target/i386/cpu-apic.c     |  2 +-
 target/i386/cpu.c          |  4 ++--
 target/i386/monitor.c      |  4 ++--
 target/m68k/monitor.c      |  2 +-
 target/ppc/monitor.c       |  2 +-
 target/riscv/monitor.c     |  2 +-
 target/sh4/monitor.c       |  2 +-
 target/sparc/monitor.c     |  2 +-
 target/xtensa/monitor.c    |  2 +-
 17 files changed, 54 insertions(+), 57 deletions(-)

diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
index 4e2f0c212b0d..702c798ccc56 100644
--- a/hw/core/machine-hmp-cmds.c
+++ b/hw/core/machine-hmp-cmds.c
@@ -36,7 +36,7 @@ void hmp_info_cpus(MonitorHMP *hmp, const QDict *qdict)
         g_autofree char *cpu_model = cpu_model_from_type(cpu->value->qom_type);
         int active = ' ';
 
-        if (cpu->value->cpu_index == monitor_get_cpu_index(mon)) {
+        if (cpu->value->cpu_index == monitor_hmp_get_cpu_index(hmp)) {
             active = '*';
         }
 
@@ -228,7 +228,7 @@ void hmp_memsave(MonitorHMP *hmp, const QDict *qdict)
     const char *filename = qdict_get_str(qdict, "filename");
     uint64_t addr = qdict_get_int(qdict, "val");
     Error *err = NULL;
-    int cpu_index = monitor_get_cpu_index(mon);
+    int cpu_index = monitor_hmp_get_cpu_index(hmp);
 
     if (cpu_index < 0) {
         monitor_printf(mon, "No CPU available\n");
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index 6aa562ddbaa2..3fd17048b319 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -30,7 +30,7 @@ OBJECT_DECLARE_TYPE(MonitorHMP, MonitorHMPClass, MONITOR_HMP);
 struct MonitorDef {
     const char *name;
     int offset;
-    int64_t (*get_value)(Monitor *mon, const MonitorDef *md, int offset);
+    int64_t (*get_value)(MonitorHMP *hmp, const MonitorDef *md, int offset);
 };
 
 void monitor_new_hmp(const char *id, const char *chardev_id,
@@ -53,8 +53,9 @@ void monitor_register_hmp_info_hrt(const char *name,
                                    HumanReadableText *(*handler)(Error **errp));
 
 
-CPUArchState *mon_get_cpu_env(Monitor *mon);
-CPUState *mon_get_cpu(Monitor *mon);
+CPUArchState *monitor_hmp_get_cpu_env(MonitorHMP *hmp);
+CPUState *monitor_hmp_get_cpu(MonitorHMP *hmp);
+int monitor_hmp_get_cpu_index(MonitorHMP *hmp);
 
 bool hmp_handle_error(MonitorHMP *hmp, Error *err);
 void hmp_help_cmd(Monitor *mon, const char *name);
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 72a8f6ea5b4f..2a550aec023f 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -39,7 +39,6 @@ int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp);
 
 int monitor_puts(Monitor *mon, const char *str);
 void monitor_flush(Monitor *mon);
-int monitor_get_cpu_index(Monitor *mon);
 
 int monitor_puts_locked(Monitor *mon, const char *str);
 void monitor_flush_locked(Monitor *mon);
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index d1e7e4de6585..89cc19c2431d 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -182,10 +182,10 @@ void hmp_cpu(MonitorHMP *hmp, const QDict *qdict)
     Monitor *mon = MONITOR(hmp);
     int64_t cpu_index;
 
-    /* XXX: drop the monitor_set_cpu() usage when all HMP commands that
+    /* XXX: drop the monitor_hmp_set_cpu() usage when all HMP commands that
             use it are converted to the QAPI */
     cpu_index = qdict_get_int(qdict, "index");
-    if (monitor_set_cpu(mon, cpu_index) < 0) {
+    if (monitor_hmp_set_cpu(hmp, cpu_index) < 0) {
         monitor_printf(mon, "invalid CPU index\n");
     }
 }
@@ -512,39 +512,37 @@ void hmp_dumpdtb(MonitorHMP *hmp, const QDict *qdict)
 #endif
 
 /* Set the current CPU defined by the user. Callers must hold BQL. */
-int monitor_set_cpu(Monitor *mon, int cpu_index)
+int monitor_hmp_set_cpu(MonitorHMP *hmp, int cpu_index)
 {
-    MonitorHMP *hmp_mon = MONITOR_HMP(mon);
     CPUState *cpu;
 
     cpu = qemu_get_cpu(cpu_index);
     if (cpu == NULL) {
         return -1;
     }
-    g_free(hmp_mon->mon_cpu_path);
-    hmp_mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
+    g_free(hmp->mon_cpu_path);
+    hmp->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
     return 0;
 }
 
 /* Callers must hold BQL. */
-static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize)
+static CPUState *monitor_hmp_get_cpu_sync(MonitorHMP *hmp, bool synchronize)
 {
-    MonitorHMP *hmp_mon = MONITOR_HMP(mon);
     CPUState *cpu = NULL;
 
-    if (hmp_mon->mon_cpu_path) {
-        cpu = (CPUState *) object_resolve_path_type(hmp_mon->mon_cpu_path,
+    if (hmp->mon_cpu_path) {
+        cpu = (CPUState *) object_resolve_path_type(hmp->mon_cpu_path,
                                                     TYPE_CPU, NULL);
         if (!cpu) {
-            g_free(hmp_mon->mon_cpu_path);
-            hmp_mon->mon_cpu_path = NULL;
+            g_free(hmp->mon_cpu_path);
+            hmp->mon_cpu_path = NULL;
         }
     }
-    if (!hmp_mon->mon_cpu_path) {
+    if (!hmp->mon_cpu_path) {
         if (!first_cpu) {
             return NULL;
         }
-        monitor_set_cpu(mon, first_cpu->cpu_index);
+        monitor_hmp_set_cpu(hmp, first_cpu->cpu_index);
         cpu = first_cpu;
     }
     assert(cpu != NULL);
@@ -554,21 +552,21 @@ static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize)
     return cpu;
 }
 
-CPUState *mon_get_cpu(Monitor *mon)
+CPUState *monitor_hmp_get_cpu(MonitorHMP *hmp)
 {
-    return mon_get_cpu_sync(mon, true);
+    return monitor_hmp_get_cpu_sync(hmp, true);
 }
 
-CPUArchState *mon_get_cpu_env(Monitor *mon)
+CPUArchState *monitor_hmp_get_cpu_env(MonitorHMP *hmp)
 {
-    CPUState *cs = mon_get_cpu(mon);
+    CPUState *cs = monitor_hmp_get_cpu(hmp);
 
     return cs ? cpu_env(cs) : NULL;
 }
 
-int monitor_get_cpu_index(Monitor *mon)
+int monitor_hmp_get_cpu_index(MonitorHMP *hmp)
 {
-    CPUState *cs = mon_get_cpu_sync(mon, false);
+    CPUState *cs = monitor_hmp_get_cpu_sync(hmp, false);
 
     return cs ? cs->cpu_index : UNASSIGNED_CPU_INDEX;
 }
@@ -586,7 +584,7 @@ void hmp_info_registers(MonitorHMP *hmp, const QDict *qdict)
             cpu_dump_state(cs, NULL, CPU_DUMP_FPU | CPU_DUMP_VPU);
         }
     } else {
-        cs = vcpu >= 0 ? qemu_get_cpu(vcpu) : mon_get_cpu(mon);
+        cs = vcpu >= 0 ? qemu_get_cpu(vcpu) : monitor_hmp_get_cpu(hmp);
 
         if (!cs) {
             if (vcpu >= 0) {
@@ -602,13 +600,14 @@ void hmp_info_registers(MonitorHMP *hmp, const QDict *qdict)
     }
 }
 
-static void memory_dump(Monitor *mon, int count, int format, int wsize,
+static void memory_dump(MonitorHMP *hmp, int count, int format, int wsize,
                         uint64_t addr, bool is_physical)
 {
+    Monitor *mon = MONITOR(hmp);
     int l, line_size, i, max_digits, len;
     uint8_t buf[16];
     uint64_t v;
-    CPUState *cs = mon_get_cpu(mon);
+    CPUState *cs = monitor_hmp_get_cpu(hmp);
     const unsigned int addr_width = is_physical ? 8 : (target_long_bits() / 4);
     const bool big_endian = target_big_endian();
 
@@ -712,24 +711,22 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
 
 void hmp_memory_dump(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int count = qdict_get_int(qdict, "count");
     int format = qdict_get_int(qdict, "format");
     int size = qdict_get_int(qdict, "size");
     vaddr addr = qdict_get_int(qdict, "addr");
 
-    memory_dump(mon, count, format, size, addr, false);
+    memory_dump(hmp, count, format, size, addr, false);
 }
 
 void hmp_physical_memory_dump(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int count = qdict_get_int(qdict, "count");
     int format = qdict_get_int(qdict, "format");
     int size = qdict_get_int(qdict, "size");
     hwaddr addr = qdict_get_int(qdict, "addr");
 
-    memory_dump(mon, count, format, size, addr, true);
+    memory_dump(hmp, count, format, size, addr, true);
 }
 
 void hmp_gpa2hva(MonitorHMP *hmp, const QDict *qdict)
@@ -757,7 +754,7 @@ void hmp_gva2gpa(MonitorHMP *hmp, const QDict *qdict)
 {
     Monitor *mon = MONITOR(hmp);
     vaddr addr = qdict_get_int(qdict, "addr");
-    CPUState *cs = mon_get_cpu(mon);
+    CPUState *cs = monitor_hmp_get_cpu(hmp);
     TranslateForDebugResult tres;
 
     if (!cs) {
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 47fb7cef6de2..2484a2310dff 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -411,10 +411,10 @@ void hmp_help_cmd(Monitor *mon, const char *name)
  * Set @pval to the value in the register identified by @name.
  * return %true if the register is found, %false otherwise.
  */
-static bool gdb_get_register(Monitor *mon, int64_t *pval, const char *name)
+static bool gdb_get_register(MonitorHMP *hmp, int64_t *pval, const char *name)
 {
     g_autoptr(GArray) regs = NULL;
-    CPUState *cs = mon_get_cpu(mon);
+    CPUState *cs = monitor_hmp_get_cpu(hmp);
 
     if (cs == NULL) {
         return false;
@@ -452,7 +452,7 @@ static bool gdb_get_register(Monitor *mon, int64_t *pval, const char *name)
 static const char *pch;
 static sigjmp_buf expr_env;
 
-static int get_monitor_def(Monitor *mon, int64_t *pval, const char *name);
+static int get_monitor_def(MonitorHMP *mon, int64_t *pval, const char *name);
 
 static G_NORETURN G_GNUC_PRINTF(2, 3)
 void expr_error(Monitor *mon, const char *fmt, ...)
@@ -535,8 +535,8 @@ static int64_t expr_unary(Monitor *mon)
                 pch++;
             }
             *q = 0;
-            if (!gdb_get_register(mon, &reg, buf)
-                && get_monitor_def(mon, &reg, buf) < 0) {
+            if (!gdb_get_register(MONITOR_HMP(mon), &reg, buf)
+                && get_monitor_def(MONITOR_HMP(mon), &reg, buf) < 0) {
                 expr_error(mon, "unknown register");
             }
             n = reg;
@@ -1733,9 +1733,9 @@ void monitor_register_hmp_info_hrt(const char *name,
  * Set @pval to the value in the register identified by @name.
  * return 0 if OK, -1 if not found
  */
-static int get_monitor_def(Monitor *mon, int64_t *pval, const char *name)
+static int get_monitor_def(MonitorHMP *hmp, int64_t *pval, const char *name)
 {
-    CPUState *cs = mon_get_cpu(mon);
+    CPUState *cs = monitor_hmp_get_cpu(hmp);
     const MonitorDef *md;
     void *ptr;
 
@@ -1750,9 +1750,9 @@ static int get_monitor_def(Monitor *mon, int64_t *pval, const char *name)
     for (; md->name != NULL; md++) {
         if (hmp_compare_cmd(name, md->name)) {
             if (md->get_value) {
-                *pval = md->get_value(mon, md, md->offset);
+                *pval = md->get_value(hmp, md, md->offset);
             } else {
-                CPUArchState *env = mon_get_cpu_env(mon);
+                CPUArchState *env = monitor_hmp_get_cpu_env(hmp);
                 ptr = (uint8_t *)env + md->offset;
                 *pval = *(int32_t *)ptr;
             }
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index a0fa37c887ed..afdda1386080 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -215,7 +215,7 @@ int monitor_can_read(void *opaque);
 void monitor_cancel_out_watch(Monitor *mon);
 void monitor_list_append(Monitor *mon);
 void monitor_fdsets_cleanup(void);
-int monitor_set_cpu(Monitor *mon, int cpu_index);
+int monitor_hmp_set_cpu(MonitorHMP *mon, int cpu_index);
 
 void qmp_send_response(MonitorQMP *mon, const QDict *rsp);
 void monitor_data_destroy_qmp(MonitorQMP *mon);
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 6cb0b587fbd4..b16119f4858c 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -169,7 +169,7 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
     MonitorHMP *hmp = MONITOR_HMP(object_new(TYPE_MONITOR_HMP));
 
     if (has_cpu_index) {
-        int ret = monitor_set_cpu(&hmp->parent_obj, cpu_index);
+        int ret = monitor_hmp_set_cpu(hmp, cpu_index);
         if (ret < 0) {
             error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",
                        "a CPU number");
diff --git a/stats/stats-hmp-cmds.c b/stats/stats-hmp-cmds.c
index f280ad8c4314..cd1f1deb58bc 100644
--- a/stats/stats-hmp-cmds.c
+++ b/stats/stats-hmp-cmds.c
@@ -226,7 +226,7 @@ void hmp_info_stats(MonitorHMP *hmp, const QDict *qdict)
         filter = stats_filter(target, names, -1, provider);
         break;
     case STATS_TARGET_VCPU: {}
-        int cpu_index = monitor_get_cpu_index(mon);
+        int cpu_index = monitor_hmp_get_cpu_index(hmp);
         filter = stats_filter(target, names, cpu_index, provider);
         break;
     case STATS_TARGET_CRYPTODEV:
diff --git a/target/i386/cpu-apic.c b/target/i386/cpu-apic.c
index 2cb3147837d1..3ae20f004b64 100644
--- a/target/i386/cpu-apic.c
+++ b/target/i386/cpu-apic.c
@@ -93,7 +93,7 @@ void hmp_info_local_apic(MonitorHMP *hmp, const QDict *qdict)
             cpu_synchronize_state(cs);
         }
     } else {
-        cs = mon_get_cpu(mon);
+        cs = monitor_hmp_get_cpu(hmp);
     }
 
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index e5ffb10d1565..f0687b5c482d 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10853,10 +10853,10 @@ static const Property x86_cpu_properties[] = {
 
 #ifndef CONFIG_USER_ONLY
 
-static int64_t monitor_get_pc(Monitor *mon, const struct MonitorDef *md,
+static int64_t monitor_get_pc(MonitorHMP *hmp, const struct MonitorDef *md,
                               int offset)
 {
-    CPUArchState *env = mon_get_cpu_env(mon);
+    CPUArchState *env = monitor_hmp_get_cpu_env(hmp);
     int64_t ret = env->eip + env->segs[R_CS].base;
 
     if (!(env->hflags & HF_CS64_MASK)) {
diff --git a/target/i386/monitor.c b/target/i386/monitor.c
index f68dd38ac225..72bcab131f77 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -215,7 +215,7 @@ void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
     CPUArchState *env;
     AddressSpace *as;
 
-    env = mon_get_cpu_env(mon);
+    env = monitor_hmp_get_cpu_env(hmp);
     if (!env) {
         monitor_printf(mon, "No CPU available\n");
         return;
@@ -542,7 +542,7 @@ void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
     CPUArchState *env;
     AddressSpace *as;
 
-    env = mon_get_cpu_env(mon);
+    env = monitor_hmp_get_cpu_env(hmp);
     if (!env) {
         monitor_printf(mon, "No CPU available\n");
         return;
diff --git a/target/m68k/monitor.c b/target/m68k/monitor.c
index 0414474f2ffb..5645a5d4d4f5 100644
--- a/target/m68k/monitor.c
+++ b/target/m68k/monitor.c
@@ -13,7 +13,7 @@
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
     Monitor *mon = MONITOR(hmp);
-    CPUArchState *env1 = mon_get_cpu_env(mon);
+    CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
 
     if (!env1) {
         monitor_printf(mon, "No CPU available\n");
diff --git a/target/ppc/monitor.c b/target/ppc/monitor.c
index 99eda7351877..5769829bdd7e 100644
--- a/target/ppc/monitor.c
+++ b/target/ppc/monitor.c
@@ -14,7 +14,7 @@
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
     Monitor *mon = MONITOR(hmp);
-    CPUArchState *env1 = mon_get_cpu_env(mon);
+    CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
 
     if (!env1) {
         monitor_printf(mon, "No CPU available\n");
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
index 496d519c978d..4c9c0c793b36 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -220,7 +220,7 @@ void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
     Monitor *mon = MONITOR(hmp);
     CPUArchState *env;
 
-    env = mon_get_cpu_env(mon);
+    env = monitor_hmp_get_cpu_env(hmp);
     if (!env) {
         monitor_printf(mon, "No CPU available\n");
         return;
diff --git a/target/sh4/monitor.c b/target/sh4/monitor.c
index 50da650b2e04..4e443152bf56 100644
--- a/target/sh4/monitor.c
+++ b/target/sh4/monitor.c
@@ -41,7 +41,7 @@ static void print_tlb(Monitor *mon, int idx, tlb_t *tlb)
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
     Monitor *mon = MONITOR(hmp);
-    CPUArchState *env = mon_get_cpu_env(mon);
+    CPUArchState *env = monitor_hmp_get_cpu_env(hmp);
     int i;
 
     if (!env) {
diff --git a/target/sparc/monitor.c b/target/sparc/monitor.c
index 09a15b821a1a..e826e584a918 100644
--- a/target/sparc/monitor.c
+++ b/target/sparc/monitor.c
@@ -30,7 +30,7 @@
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
     Monitor *mon = MONITOR(hmp);
-    CPUArchState *env1 = mon_get_cpu_env(mon);
+    CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
 
     if (!env1) {
         monitor_printf(mon, "No CPU available\n");
diff --git a/target/xtensa/monitor.c b/target/xtensa/monitor.c
index a1082c44e11c..b7b7387706f3 100644
--- a/target/xtensa/monitor.c
+++ b/target/xtensa/monitor.c
@@ -29,7 +29,7 @@
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
     Monitor *mon = MONITOR(hmp);
-    CPUArchState *env1 = mon_get_cpu_env(mon);
+    CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
 
     if (!env1) {
         monitor_printf(mon, "No CPU available\n");

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 37/49] monitor: tighten monitor_printf*()
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (35 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 36/49] monitor: tighten monitor_set_cpu()/get_cpu() Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-17 18:09   ` Jason J. Herne
  2026-08-16 19:13 ` [PATCH v3 38/49] hexagon: make dump_mmu() take MonitorHMP Marc-André Lureau
                   ` (11 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Gerd Hoffmann,
	Gonglei (Arei), zhenwei pi, Kevin Wolf, Hanna Reitz,
	Paolo Bonzini, Alex Bennée, Pierrick Bouvier, Ani Sinha,
	Laurent Vivier, Amit Shah, Michael S. Tsirkin, Brian Cain,
	David Woodhouse, Paul Durrant, Richard Henderson, Marcelo Tosatti,
	Mark Cave-Ayland, Jiri Pirko, Jason Wang, Halil Pasic,
	Christian Borntraeger, Jason Herne, Cornelia Huck, Eric Farman,
	Matthew Rosato, Ilya Leoshkevich, David Hildenbrand,
	Stefano Stabellini, Anthony PERARD, Edgar E. Iglesias,
	Dr. David Alan Gilbert, Hyman Huang, Peter Xu, Fabiano Rosas,
	Samuel Thibault, Stefan Berger, Zhao Liu, Nicholas Piggin,
	Chinmay Rath, Glenn Miles, Harsh Prateek Bora, Palmer Dabbelt,
	Alistair Francis, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei,
	Chao Liu, Yoshinori Sato, Artyom Tarasenko, Max Filippov,
	Stefan Hajnoczi, qemu-block, kvm, qemu-ppc, qemu-s390x, xen-devel,
	qemu-riscv

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.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 audio/audio-hmp-cmds.c                  |   6 +-
 backends/cryptodev-hmp-cmds.c           |   9 +-
 block/monitor/block-hmp-cmds.c          | 170 +++++++++---------
 chardev/char-hmp-cmds.c                 |  12 +-
 disas/disas-mon.c                       |  10 +-
 docs/devel/style.rst                    |   2 +-
 docs/devel/writing-monitor-commands.rst |   8 +-
 dump/dump-hmp-cmds.c                    |   5 +-
 hw/char/virtio-serial-bus.c             |  10 +-
 hw/core/machine-hmp-cmds.c              | 213 +++++++++++-----------
 hw/core/sysbus.c                        |   5 +-
 hw/hexagon/hexagon_tlb.c                |  44 ++---
 hw/i386/kvm/xen-stubs.c                 |   6 +-
 hw/i386/kvm/xen_evtchn.c                |  21 +--
 hw/i386/sgx-hmp-stub.c                  |   3 +-
 hw/i386/sgx.c                           |  29 ++-
 hw/misc/auxbus.c                        |   9 +-
 hw/misc/mos6522-stub.c                  |   3 +-
 hw/net/rocker/rocker-hmp-cmds.c         | 146 ++++++++-------
 hw/pci/pci-hmp-cmds.c                   | 114 ++++++------
 hw/pci/pci-stub.c                       |   3 +-
 hw/s390x/s390-skeys.c                   |   9 +-
 hw/s390x/s390-stattrib.c                |  20 +--
 hw/uefi/ovmf-log.c                      |   5 +-
 hw/usb/bus.c                            |  11 +-
 hw/usb/host-libusb.c                    |  21 ++-
 hw/virtio/virtio-hmp-cmds.c             | 297 +++++++++++++++----------------
 hw/xen/xen-bus.c                        |   5 +-
 include/disas/disas.h                   |   4 +-
 include/monitor/hmp.h                   |  12 +-
 migration/dirtyrate.c                   |  46 +++--
 migration/migration-hmp-cmds.c          | 305 ++++++++++++++++----------------
 monitor/hmp-cmds.c                      | 141 +++++++--------
 monitor/hmp.c                           | 143 +++++++--------
 monitor/monitor-internal.h              |   6 -
 monitor/monitor.c                       |  33 ++--
 net/net-hmp-cmds.c                      |  31 ++--
 net/slirp.c                             |  31 ++--
 qom/qom-hmp-cmds.c                      |  27 ++-
 replay/replay-debugging.c               |   5 +-
 stats/stats-hmp-cmds.c                  |  57 +++---
 stubs/hmp-cmd-info_sev.c                |   3 +-
 stubs/monitor-core.c                    |   2 +-
 system/dirtylimit-hmp-cmds.c            |  10 +-
 system/qdev-monitor.c                   |  19 +-
 system/runstate-hmp-cmds.c              |  16 +-
 system/tpm-hmp-cmds.c                   |  29 ++-
 target/i386/cpu-apic.c                  |   3 +-
 target/i386/monitor.c                   | 152 ++++++++--------
 target/i386/sev.c                       |  35 ++--
 target/m68k/monitor.c                   |   3 +-
 target/ppc/monitor.c                    |   3 +-
 target/riscv/monitor.c                  |  55 +++---
 target/sh4/monitor.c                    |  29 ++-
 target/sparc/monitor.c                  |   3 +-
 target/xtensa/monitor.c                 |   3 +-
 tests/unit/test-util-sockets.c          |   2 +-
 tools/qemu-vnc/clipboard.c              |   4 +-
 tools/qemu-vnc/stubs.c                  |   2 +-
 trace/trace-hmp-cmds.c                  |  12 +-
 ui/ui-hmp-cmds.c                        | 115 ++++++------
 util/error-report.c                     |   2 +-
 util/qemu-print.c                       |   4 +-
 63 files changed, 1214 insertions(+), 1329 deletions(-)

diff --git a/audio/audio-hmp-cmds.c b/audio/audio-hmp-cmds.c
index 4d326ec99fdf..94182fe1d71f 100644
--- a/audio/audio-hmp-cmds.c
+++ b/audio/audio-hmp-cmds.c
@@ -34,14 +34,13 @@ static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
 
 void hmp_info_capture(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int i;
     CaptureState *s;
 
     warn_report_once("'info capture' is deprecated since v10.2, to be removed");
 
     for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
-        monitor_printf(mon, "[%d]: ", i);
+        monitor_hmp_printf(hmp, "[%d]: ", i);
         s->ops.info (s->opaque);
     }
 }
@@ -66,7 +65,6 @@ void hmp_stopcapture(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_wavcapture(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *path = qdict_get_str(qdict, "path");
     int freq = qdict_get_try_int(qdict, "freq", 44100);
     int bits = qdict_get_try_int(qdict, "bits", 16);
@@ -86,7 +84,7 @@ void hmp_wavcapture(MonitorHMP *hmp, const QDict *qdict)
     s = g_malloc0 (sizeof (*s));
 
     if (wav_start_capture(as, s, path, freq, bits, nchannels)) {
-        monitor_printf(mon, "Failed to add wave capture\n");
+        monitor_hmp_printf(hmp, "Failed to add wave capture\n");
         g_free (s);
         return;
     }
diff --git a/backends/cryptodev-hmp-cmds.c b/backends/cryptodev-hmp-cmds.c
index fb62428d795a..aafa4b970d24 100644
--- a/backends/cryptodev-hmp-cmds.c
+++ b/backends/cryptodev-hmp-cmds.c
@@ -19,7 +19,6 @@
 
 void hmp_info_cryptodev(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     QCryptodevInfoList *il;
     QCryptodevBackendServiceTypeList *sl;
     QCryptodevBackendClientList *cl;
@@ -41,13 +40,13 @@ void hmp_info_cryptodev(MonitorHMP *hmp, const QDict *qdict)
                 services = tmp_services;
             }
         }
-        monitor_printf(mon, "%s: service=[%s]\n", info->id, services);
+        monitor_hmp_printf(hmp, "%s: service=[%s]\n", info->id, services);
 
         for (cl = info->client; cl; cl = cl->next) {
             QCryptodevBackendClient *client = cl->value;
-            monitor_printf(mon, "    queue %" PRIu32 ": type=%s\n",
-                           client->queue,
-                           QCryptodevBackendType_str(client->type));
+            monitor_hmp_printf(hmp, "    queue %" PRIu32 ": type=%s\n",
+                               client->queue,
+                               QCryptodevBackendType_str(client->type));
         }
     }
 
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index a2666e2f1b9b..7bae4d425c6d 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -89,7 +89,6 @@ out:
 
 void hmp_drive_add(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     DriveInfo *dinfo;
     QemuOpts *opts;
@@ -119,7 +118,7 @@ void hmp_drive_add(MonitorHMP *hmp, const QDict *qdict)
 
     switch (dinfo->type) {
     case IF_NONE:
-        monitor_printf(mon, "OK\n");
+        monitor_hmp_printf(hmp, "OK\n");
         break;
     default:
         error_setg(&err, "Can't hot-add drive to type %d", dinfo->type);
@@ -552,9 +551,10 @@ void hmp_qemu_io(MonitorHMP *hmp, const QDict *qdict)
     hmp_handle_error(hmp, err);
 }
 
-static void print_block_info(Monitor *mon, BlockInfo *info,
+static void print_block_info(MonitorHMP *hmp, BlockInfo *info,
                              BlockDeviceInfo *inserted, bool verbose)
 {
+    Monitor *mon = MONITOR(hmp);
     ImageInfo *image_info;
 
     assert(!info || !info->inserted || info->inserted == inserted);
@@ -562,7 +562,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
     if (info && *info->device) {
         monitor_puts(mon, info->device);
         if (inserted && inserted->node_name) {
-            monitor_printf(mon, " (%s)", inserted->node_name);
+            monitor_hmp_printf(hmp, " (%s)", inserted->node_name);
         }
     } else {
         assert(info || inserted);
@@ -573,29 +573,29 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
     }
 
     if (inserted) {
-        monitor_printf(mon, ": %s (%s%s%s%s)\n",
-                       inserted->file,
-                       inserted->drv,
-                       inserted->ro ? ", read-only" : "",
-                       inserted->encrypted ? ", encrypted" : "",
-                       inserted->active ? "" : ", inactive");
+        monitor_hmp_printf(hmp, ": %s (%s%s%s%s)\n",
+                           inserted->file,
+                           inserted->drv,
+                           inserted->ro ? ", read-only" : "",
+                           inserted->encrypted ? ", encrypted" : "",
+                           inserted->active ? "" : ", inactive");
     } else {
-        monitor_printf(mon, ": [not inserted]\n");
+        monitor_hmp_printf(hmp, ": [not inserted]\n");
     }
 
     if (info) {
         if (info->qdev) {
-            monitor_printf(mon, "    Attached to:      %s\n", info->qdev);
+            monitor_hmp_printf(hmp, "    Attached to:      %s\n", info->qdev);
         }
         if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
-            monitor_printf(mon, "    I/O status:       %s\n",
-                           BlockDeviceIoStatus_str(info->io_status));
+            monitor_hmp_printf(hmp, "    I/O status:       %s\n",
+                               BlockDeviceIoStatus_str(info->io_status));
         }
 
         if (info->removable) {
-            monitor_printf(mon, "    Removable device: %slocked, tray %s\n",
-                           info->locked ? "" : "not ",
-                           info->tray_open ? "open" : "closed");
+            monitor_hmp_printf(hmp, "    Removable device: %slocked, tray %s\n",
+                               info->locked ? "" : "not ",
+                               info->tray_open ? "open" : "closed");
         }
     }
 
@@ -604,28 +604,28 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
         return;
     }
 
-    monitor_printf(mon, "    Cache mode:       %s%s%s\n",
-                   inserted->cache->writeback ? "writeback" : "writethrough",
-                   inserted->cache->direct ? ", direct" : "",
-                   inserted->cache->no_flush ? ", ignore flushes" : "");
+    monitor_hmp_printf(hmp, "    Cache mode:       %s%s%s\n",
+                       inserted->cache->writeback ? "writeback" : "writethrough",
+                       inserted->cache->direct ? ", direct" : "",
+                       inserted->cache->no_flush ? ", ignore flushes" : "");
 
     if (inserted->backing_file) {
-        monitor_printf(mon,
-                       "    Backing file:     %s "
-                       "(chain depth: %" PRId64 ")\n",
-                       inserted->backing_file,
-                       inserted->backing_file_depth);
+        monitor_hmp_printf(hmp,
+                           "    Backing file:     %s "
+                           "(chain depth: %" PRId64 ")\n",
+                           inserted->backing_file,
+                           inserted->backing_file_depth);
     }
 
     if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
-        monitor_printf(mon, "    Detect zeroes:    %s\n",
+        monitor_hmp_printf(hmp, "    Detect zeroes:    %s\n",
                 BlockdevDetectZeroesOptions_str(inserted->detect_zeroes));
     }
 
     if (inserted->bps  || inserted->bps_rd  || inserted->bps_wr  ||
         inserted->iops || inserted->iops_rd || inserted->iops_wr)
     {
-        monitor_printf(mon, "    I/O throttling:   bps=%" PRId64
+        monitor_hmp_printf(hmp, "    I/O throttling:   bps=%" PRId64
                         " bps_rd=%" PRId64  " bps_wr=%" PRId64
                         " bps_max=%" PRId64
                         " bps_rd_max=%" PRId64
@@ -654,7 +654,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
     }
 
     if (verbose) {
-        monitor_printf(mon, "\nImages:\n");
+        monitor_hmp_printf(hmp, "\nImages:\n");
         image_info = inserted->image;
         while (1) {
             bdrv_node_info_dump(qapi_ImageInfo_base(image_info), 0, false);
@@ -669,7 +669,6 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
 
 void hmp_info_block(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     BlockInfoList *block_list, *info;
     BlockDeviceInfoList *blockdev_list, *blockdev;
     const char *device = qdict_get_try_str(qdict, "device");
@@ -690,10 +689,10 @@ void hmp_info_block(MonitorHMP *hmp, const QDict *qdict)
         }
 
         if (info != block_list) {
-            monitor_printf(mon, "\n");
+            monitor_hmp_printf(hmp, "\n");
         }
 
-        print_block_info(mon, info->value, info->value->inserted,
+        print_block_info(hmp, info->value, info->value->inserted,
                          verbose);
         printed = true;
     }
@@ -713,17 +712,16 @@ void hmp_info_block(MonitorHMP *hmp, const QDict *qdict)
         }
 
         if (blockdev != blockdev_list) {
-            monitor_printf(mon, "\n");
+            monitor_hmp_printf(hmp, "\n");
         }
 
-        print_block_info(mon, NULL, blockdev->value, verbose);
+        print_block_info(hmp, NULL, blockdev->value, verbose);
     }
     qapi_free_BlockDeviceInfoList(blockdev_list);
 }
 
 void hmp_info_blockstats(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     BlockStatsList *stats_list, *stats;
 
     stats_list = qmp_query_blockstats(false, false, NULL);
@@ -733,28 +731,28 @@ void hmp_info_blockstats(MonitorHMP *hmp, const QDict *qdict)
             continue;
         }
 
-        monitor_printf(mon, "%s%s: idle_time_ns=%" PRId64 "\n",
-                       stats != stats_list ? "\n" : "",
-                       stats->value->device,
-                       stats->value->stats->idle_time_ns);
-        monitor_printf(mon, "       %24s %16s %24s %10s\n", "bytes",
-                       "operations", "total_time_ns", "merged");
-        monitor_printf(mon, "Read:  %24" PRId64 " %16" PRId64 " %24" PRId64
-                       " %10" PRId64 "\n",
-                       stats->value->stats->rd_bytes,
-                       stats->value->stats->rd_operations,
-                       stats->value->stats->rd_total_time_ns,
-                       stats->value->stats->rd_merged);
-        monitor_printf(mon, "Write: %24" PRId64 " %16" PRId64 " %24" PRId64
-                       " %10" PRId64 "\n",
-                       stats->value->stats->wr_bytes,
-                       stats->value->stats->wr_operations,
-                       stats->value->stats->wr_total_time_ns,
-                       stats->value->stats->wr_merged);
-        monitor_printf(mon, "Flush: %24s %16" PRId64 " %24" PRId64 "\n",
-                       "",
-                       stats->value->stats->flush_operations,
-                       stats->value->stats->flush_total_time_ns);
+        monitor_hmp_printf(hmp, "%s%s: idle_time_ns=%" PRId64 "\n",
+                           stats != stats_list ? "\n" : "",
+                           stats->value->device,
+                           stats->value->stats->idle_time_ns);
+        monitor_hmp_printf(hmp, "       %24s %16s %24s %10s\n", "bytes",
+                           "operations", "total_time_ns", "merged");
+        monitor_hmp_printf(hmp, "Read:  %24" PRId64 " %16" PRId64 " %24" PRId64
+                           " %10" PRId64 "\n",
+                           stats->value->stats->rd_bytes,
+                           stats->value->stats->rd_operations,
+                           stats->value->stats->rd_total_time_ns,
+                           stats->value->stats->rd_merged);
+        monitor_hmp_printf(hmp, "Write: %24" PRId64 " %16" PRId64 " %24" PRId64
+                           " %10" PRId64 "\n",
+                           stats->value->stats->wr_bytes,
+                           stats->value->stats->wr_operations,
+                           stats->value->stats->wr_total_time_ns,
+                           stats->value->stats->wr_merged);
+        monitor_hmp_printf(hmp, "Flush: %24s %16" PRId64 " %24" PRId64 "\n",
+                           "",
+                           stats->value->stats->flush_operations,
+                           stats->value->stats->flush_total_time_ns);
     }
 
     qapi_free_BlockStatsList(stats_list);
@@ -762,34 +760,33 @@ void hmp_info_blockstats(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_block_jobs(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     BlockJobInfoList *list;
 
     list = qmp_query_block_jobs(&error_abort);
 
     if (!list) {
-        monitor_printf(mon, "No active jobs\n");
+        monitor_hmp_printf(hmp, "No active jobs\n");
         return;
     }
 
     while (list) {
         if (list->value->type == JOB_TYPE_STREAM) {
-            monitor_printf(mon, "Streaming device %s: Completed %" PRId64
-                           " of %" PRId64 " bytes, speed limit %" PRId64
-                           " bytes/s\n",
-                           list->value->device,
-                           list->value->offset,
-                           list->value->len,
-                           list->value->speed);
+            monitor_hmp_printf(hmp, "Streaming device %s: Completed %" PRId64
+                               " of %" PRId64 " bytes, speed limit %" PRId64
+                               " bytes/s\n",
+                               list->value->device,
+                               list->value->offset,
+                               list->value->len,
+                               list->value->speed);
         } else {
-            monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
-                           " of %" PRId64 " bytes, speed limit %" PRId64
-                           " bytes/s\n",
-                           JobType_str(list->value->type),
-                           list->value->device,
-                           list->value->offset,
-                           list->value->len,
-                           list->value->speed);
+            monitor_hmp_printf(hmp, "Type %s, device %s: Completed %" PRId64
+                               " of %" PRId64 " bytes, speed limit %" PRId64
+                               " bytes/s\n",
+                               JobType_str(list->value->type),
+                               list->value->device,
+                               list->value->offset,
+                               list->value->len,
+                               list->value->speed);
         }
         list = list->next;
     }
@@ -799,7 +796,6 @@ void hmp_info_block_jobs(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_snapshots(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     BlockDriverState *bs, *bs1;
     BdrvNextIterator it1;
     QEMUSnapshotInfo *sn_tab, *sn;
@@ -837,7 +833,7 @@ void hmp_info_snapshots(MonitorHMP *hmp, const QDict *qdict)
     nb_sns = bdrv_snapshot_list(bs, &sn_tab);
 
     if (nb_sns < 0) {
-        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
+        monitor_hmp_printf(hmp, "bdrv_snapshot_list: error %d\n", nb_sns);
         return;
     }
 
@@ -866,7 +862,7 @@ void hmp_info_snapshots(MonitorHMP *hmp, const QDict *qdict)
     }
 
     if (no_snapshot) {
-        monitor_printf(mon, "There is no snapshot available.\n");
+        monitor_hmp_printf(hmp, "There is no snapshot available.\n");
         return;
     }
 
@@ -889,11 +885,11 @@ void hmp_info_snapshots(MonitorHMP *hmp, const QDict *qdict)
             }
         }
     }
-    monitor_printf(mon, "List of snapshots present on all disks:\n");
+    monitor_hmp_printf(hmp, "List of snapshots present on all disks:\n");
 
     if (total > 0) {
         bdrv_snapshot_dump(NULL);
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "\n");
         for (i = 0; i < total; i++) {
             sn = &sn_tab[global_snapshots[i]];
             /*
@@ -902,24 +898,24 @@ void hmp_info_snapshots(MonitorHMP *hmp, const QDict *qdict)
              */
             pstrcpy(sn->id_str, sizeof(sn->id_str), "--");
             bdrv_snapshot_dump(sn);
-            monitor_printf(mon, "\n");
+            monitor_hmp_printf(hmp, "\n");
         }
     } else {
-        monitor_printf(mon, "None\n");
+        monitor_hmp_printf(hmp, "None\n");
     }
 
     QTAILQ_FOREACH(image_entry, &image_list, next) {
         if (QTAILQ_EMPTY(&image_entry->snapshots)) {
             continue;
         }
-        monitor_printf(mon,
-                       "\nList of partial (non-loadable) snapshots on '%s':\n",
-                       image_entry->imagename);
+        monitor_hmp_printf(hmp,
+                           "\nList of partial (non-loadable) snapshots on '%s':\n",
+                           image_entry->imagename);
         bdrv_snapshot_dump(NULL);
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "\n");
         QTAILQ_FOREACH(snapshot_entry, &image_entry->snapshots, next) {
             bdrv_snapshot_dump(&snapshot_entry->sn);
-            monitor_printf(mon, "\n");
+            monitor_hmp_printf(hmp, "\n");
         }
     }
 
@@ -935,7 +931,7 @@ void hmp_info_snapshots(MonitorHMP *hmp, const QDict *qdict)
     g_free(global_snapshots);
 }
 
-void hmp_change_medium(Monitor *mon, const char *device, const char *target,
+void hmp_change_medium(MonitorHMP *hmp, const char *device, const char *target,
                        const char *arg, const char *read_only, bool force,
                        Error **errp)
 {
diff --git a/chardev/char-hmp-cmds.c b/chardev/char-hmp-cmds.c
index 71017fd2d19e..fb0560054b7b 100644
--- a/chardev/char-hmp-cmds.c
+++ b/chardev/char-hmp-cmds.c
@@ -26,12 +26,11 @@
 
 void hmp_info_chardev(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     ChardevInfoList *char_info, *info;
 
     char_info = qmp_query_chardev(NULL);
     for (info = char_info; info; info = info->next) {
-        monitor_printf(mon, "%s: filename=%s\n", info->value->label,
+        monitor_hmp_printf(hmp, "%s: filename=%s\n", info->value->label,
                                                  info->value->filename);
     }
 
@@ -51,7 +50,6 @@ void hmp_ringbuf_write(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_ringbuf_read(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     uint32_t size = qdict_get_int(qdict, "size");
     const char *chardev = qdict_get_str(qdict, "device");
     char *data;
@@ -67,15 +65,15 @@ void hmp_ringbuf_read(MonitorHMP *hmp, const QDict *qdict)
         unsigned char ch = data[i];
 
         if (ch == '\\') {
-            monitor_printf(mon, "\\\\");
+            monitor_hmp_printf(hmp, "\\\\");
         } else if ((ch < 0x20 && ch != '\n' && ch != '\t') || ch == 0x7F) {
-            monitor_printf(mon, "\\u%04X", ch);
+            monitor_hmp_printf(hmp, "\\u%04X", ch);
         } else {
-            monitor_printf(mon, "%c", ch);
+            monitor_hmp_printf(hmp, "%c", ch);
         }
 
     }
-    monitor_printf(mon, "\n");
+    monitor_hmp_printf(hmp, "\n");
     g_free(data);
 }
 
diff --git a/disas/disas-mon.c b/disas/disas-mon.c
index bc9dec3a7761..32e4220181a8 100644
--- a/disas/disas-mon.c
+++ b/disas/disas-mon.c
@@ -38,7 +38,7 @@ physical_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length,
 }
 
 /* Disassembler for the monitor.  */
-void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc,
+void monitor_disas(MonitorHMP *hmp, CPUState *cpu, uint64_t pc,
                    int nb_insn, bool is_physical)
 {
     int count, i;
@@ -58,13 +58,13 @@ void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc,
     s.info.buffer_vma = pc;
 
     if (s.info.cap_arch >= 0 && cap_disas_monitor(&s.info, pc, nb_insn)) {
-        monitor_puts(mon, ds->str);
+        monitor_puts(MONITOR(hmp), ds->str);
         return;
     }
 
     if (!s.info.print_insn) {
-        monitor_printf(mon, "0x%08" PRIx64
-                       ": Asm output not supported on this arch\n", pc);
+        monitor_hmp_printf(hmp, "0x%08" PRIx64
+                           ": Asm output not supported on this arch\n", pc);
         return;
     }
 
@@ -78,5 +78,5 @@ void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc,
         pc += count;
     }
 
-    monitor_puts(mon, ds->str);
+    monitor_puts(MONITOR(hmp), ds->str);
 }
diff --git a/docs/devel/style.rst b/docs/devel/style.rst
index 6c5f94cc5098..6876d3a59ec7 100644
--- a/docs/devel/style.rst
+++ b/docs/devel/style.rst
@@ -754,7 +754,7 @@ Error handling and reporting
 Reporting errors to the human user
 ----------------------------------
 
-Do not use printf(), fprintf() or monitor_printf().  Instead, use
+Do not use printf(), fprintf() or monitor_hmp_printf().  Instead, use
 error_report() or error_vreport() from error-report.h.  This ensures the
 error is reported in the right place (current monitor or stderr), and in
 a uniform format.
diff --git a/docs/devel/writing-monitor-commands.rst b/docs/devel/writing-monitor-commands.rst
index 7ae7efe32759..baf94cbdefab 100644
--- a/docs/devel/writing-monitor-commands.rst
+++ b/docs/devel/writing-monitor-commands.rst
@@ -479,7 +479,7 @@ The HMP command
 
 Here's the HMP counterpart of the query-option-roms command::
 
- void hmp_info_option_roms(Monitor *mon, const QDict *qdict)
+ void hmp_info_option_roms(MonitorHMP *mon, const QDict *qdict)
  {
      Error *err = NULL;
      OptionRomInfoList *info_list, *tail;
@@ -492,11 +492,11 @@ Here's the HMP counterpart of the query-option-roms command::
 
      for (tail = info_list; tail; tail = tail->next) {
          info = tail->value;
-         monitor_printf(mon, "%s", info->filename);
+         monitor_hmp_printf(mon, "%s", info->filename);
          if (info->has_bootindex) {
-             monitor_printf(mon, " %" PRId64, info->bootindex);
+             monitor_hmp_printf(mon, " %" PRId64, info->bootindex);
          }
-         monitor_printf(mon, "\n");
+         monitor_hmp_printf(mon, "\n");
      }
 
      qapi_free_OptionRomInfoList(info_list);
diff --git a/dump/dump-hmp-cmds.c b/dump/dump-hmp-cmds.c
index 104ab5d2a53a..c7045c2d7314 100644
--- a/dump/dump-hmp-cmds.c
+++ b/dump/dump-hmp-cmds.c
@@ -85,17 +85,16 @@ void hmp_dump_guest_memory(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_dump(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     DumpQueryResult *result = qmp_query_dump(NULL);
 
     assert(result && result->status < DUMP_STATUS__MAX);
-    monitor_printf(mon, "Status: %s\n", DumpStatus_str(result->status));
+    monitor_hmp_printf(hmp, "Status: %s\n", DumpStatus_str(result->status));
 
     if (result->status == DUMP_STATUS_ACTIVE) {
         float percent = 0;
         assert(result->total != 0);
         percent = 100.0 * result->completed / result->total;
-        monitor_printf(mon, "Finished: %.2f %%\n", percent);
+        monitor_hmp_printf(hmp, "Finished: %.2f %%\n", percent);
     }
 
     qapi_free_DumpQueryResult(result);
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 02604740f86a..33fdc0846ac3 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -838,11 +838,11 @@ static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
 {
     VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(qdev);
 
-    monitor_printf(mon, "%*sport %d, guest %s, host %s, throttle %s\n",
-                   indent, "", port->id,
-                   port->guest_connected ? "on" : "off",
-                   port->host_connected ? "on" : "off",
-                   port->throttled ? "on" : "off");
+    monitor_hmp_printf(MONITOR_HMP(mon), "%*sport %d, guest %s, host %s, throttle %s\n",
+                       indent, "", port->id,
+                       port->guest_connected ? "on" : "off",
+                       port->host_connected ? "on" : "off",
+                       port->throttled ? "on" : "off");
 }
 
 /* This function is only used if a port id is not provided by the user */
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
index 702c798ccc56..10a633af0780 100644
--- a/hw/core/machine-hmp-cmds.c
+++ b/hw/core/machine-hmp-cmds.c
@@ -27,7 +27,6 @@
 
 void hmp_info_cpus(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     CpuInfoFastList *cpu_list, *cpu;
 
     cpu_list = qmp_query_cpus_fast(NULL);
@@ -40,10 +39,10 @@ void hmp_info_cpus(MonitorHMP *hmp, const QDict *qdict)
             active = '*';
         }
 
-        monitor_printf(mon, "%c CPU #%" PRId64 ":", active,
-                       cpu->value->cpu_index);
-        monitor_printf(mon, " thread_id=%" PRId64 " model=%s\n",
-                       cpu->value->thread_id, cpu_model);
+        monitor_hmp_printf(hmp, "%c CPU #%" PRId64 ":", active,
+                           cpu->value->cpu_index);
+        monitor_hmp_printf(hmp, " thread_id=%" PRId64 " model=%s\n",
+                           cpu->value->thread_id, cpu_model);
     }
 
     qapi_free_CpuInfoFastList(cpu_list);
@@ -51,7 +50,6 @@ void hmp_info_cpus(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_hotpluggable_cpus(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     HotpluggableCPUList *l = qmp_query_hotpluggable_cpus(&err);
     HotpluggableCPUList *saved = l;
@@ -61,45 +59,45 @@ void hmp_hotpluggable_cpus(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "Hotpluggable CPUs:\n");
+    monitor_hmp_printf(hmp, "Hotpluggable CPUs:\n");
     while (l) {
-        monitor_printf(mon, "  type: \"%s\"\n", l->value->type);
-        monitor_printf(mon, "  vcpus_count: \"%" PRIu64 "\"\n",
-                       l->value->vcpus_count);
+        monitor_hmp_printf(hmp, "  type: \"%s\"\n", l->value->type);
+        monitor_hmp_printf(hmp, "  vcpus_count: \"%" PRIu64 "\"\n",
+                           l->value->vcpus_count);
         if (l->value->qom_path) {
-            monitor_printf(mon, "  qom_path: \"%s\"\n", l->value->qom_path);
+            monitor_hmp_printf(hmp, "  qom_path: \"%s\"\n", l->value->qom_path);
         }
 
         c = l->value->props;
-        monitor_printf(mon, "  CPUInstance Properties:\n");
+        monitor_hmp_printf(hmp, "  CPUInstance Properties:\n");
         if (c->has_node_id) {
-            monitor_printf(mon, "    node-id: \"%" PRIu64 "\"\n", c->node_id);
+            monitor_hmp_printf(hmp, "    node-id: \"%" PRIu64 "\"\n", c->node_id);
         }
         if (c->has_drawer_id) {
-            monitor_printf(mon, "    drawer-id: \"%" PRIu64 "\"\n", c->drawer_id);
+            monitor_hmp_printf(hmp, "    drawer-id: \"%" PRIu64 "\"\n", c->drawer_id);
         }
         if (c->has_book_id) {
-            monitor_printf(mon, "    book-id: \"%" PRIu64 "\"\n", c->book_id);
+            monitor_hmp_printf(hmp, "    book-id: \"%" PRIu64 "\"\n", c->book_id);
         }
         if (c->has_socket_id) {
-            monitor_printf(mon, "    socket-id: \"%" PRIu64 "\"\n", c->socket_id);
+            monitor_hmp_printf(hmp, "    socket-id: \"%" PRIu64 "\"\n", c->socket_id);
         }
         if (c->has_die_id) {
-            monitor_printf(mon, "    die-id: \"%" PRIu64 "\"\n", c->die_id);
+            monitor_hmp_printf(hmp, "    die-id: \"%" PRIu64 "\"\n", c->die_id);
         }
         if (c->has_cluster_id) {
-            monitor_printf(mon, "    cluster-id: \"%" PRIu64 "\"\n",
-                           c->cluster_id);
+            monitor_hmp_printf(hmp, "    cluster-id: \"%" PRIu64 "\"\n",
+                               c->cluster_id);
         }
         if (c->has_module_id) {
-            monitor_printf(mon, "    module-id: \"%" PRIu64 "\"\n",
-                           c->module_id);
+            monitor_hmp_printf(hmp, "    module-id: \"%" PRIu64 "\"\n",
+                               c->module_id);
         }
         if (c->has_core_id) {
-            monitor_printf(mon, "    core-id: \"%" PRIu64 "\"\n", c->core_id);
+            monitor_hmp_printf(hmp, "    core-id: \"%" PRIu64 "\"\n", c->core_id);
         }
         if (c->has_thread_id) {
-            monitor_printf(mon, "    thread-id: \"%" PRIu64 "\"\n", c->thread_id);
+            monitor_hmp_printf(hmp, "    thread-id: \"%" PRIu64 "\"\n", c->thread_id);
         }
 
         l = l->next;
@@ -110,7 +108,6 @@ void hmp_hotpluggable_cpus(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_memdev(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     MemdevList *memdev_list = qmp_query_memdev(&err);
     MemdevList *m = memdev_list;
@@ -120,31 +117,31 @@ void hmp_info_memdev(MonitorHMP *hmp, const QDict *qdict)
     while (m) {
         v = string_output_visitor_new(false, &str);
         visit_type_uint16List(v, NULL, &m->value->host_nodes, &error_abort);
-        monitor_printf(mon, "memory backend: %s\n", m->value->id);
-        monitor_printf(mon, "  size:  %" PRId64 "\n", m->value->size);
-        monitor_printf(mon, "  merge: %s\n",
-                       m->value->merge ? "true" : "false");
-        monitor_printf(mon, "  dump: %s\n",
-                       m->value->dump ? "true" : "false");
-        monitor_printf(mon, "  prealloc: %s\n",
-                       m->value->prealloc ? "true" : "false");
-        monitor_printf(mon, "  share: %s\n",
-                       m->value->share ? "true" : "false");
+        monitor_hmp_printf(hmp, "memory backend: %s\n", m->value->id);
+        monitor_hmp_printf(hmp, "  size:  %" PRId64 "\n", m->value->size);
+        monitor_hmp_printf(hmp, "  merge: %s\n",
+                           m->value->merge ? "true" : "false");
+        monitor_hmp_printf(hmp, "  dump: %s\n",
+                           m->value->dump ? "true" : "false");
+        monitor_hmp_printf(hmp, "  prealloc: %s\n",
+                           m->value->prealloc ? "true" : "false");
+        monitor_hmp_printf(hmp, "  share: %s\n",
+                           m->value->share ? "true" : "false");
         if (m->value->has_reserve) {
-            monitor_printf(mon, "  reserve: %s\n",
-                           m->value->reserve ? "true" : "false");
+            monitor_hmp_printf(hmp, "  reserve: %s\n",
+                               m->value->reserve ? "true" : "false");
         }
-        monitor_printf(mon, "  policy: %s\n",
-                       HostMemPolicy_str(m->value->policy));
+        monitor_hmp_printf(hmp, "  policy: %s\n",
+                           HostMemPolicy_str(m->value->policy));
         visit_complete(v, &str);
-        monitor_printf(mon, "  host nodes: %s\n", str);
+        monitor_hmp_printf(hmp, "  host nodes: %s\n", str);
 
         g_free(str);
         visit_free(v);
         m = m->next;
     }
 
-    monitor_printf(mon, "\n");
+    monitor_hmp_printf(hmp, "\n");
 
     qapi_free_MemdevList(memdev_list);
     hmp_handle_error(hmp, err);
@@ -152,15 +149,14 @@ void hmp_info_memdev(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_kvm(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     KvmInfo *info;
 
     info = qmp_query_kvm(NULL);
-    monitor_printf(mon, "kvm support: ");
+    monitor_hmp_printf(hmp, "kvm support: ");
     if (info->present) {
-        monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled");
+        monitor_hmp_printf(hmp, "%s\n", info->enabled ? "enabled" : "disabled");
     } else {
-        monitor_printf(mon, "not compiled\n");
+        monitor_hmp_printf(hmp, "not compiled\n");
     }
 
     qapi_free_KvmInfo(info);
@@ -168,7 +164,6 @@ void hmp_info_kvm(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_accelerators(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     AcceleratorInfo *info;
     AcceleratorList *accel;
 
@@ -176,9 +171,9 @@ void hmp_info_accelerators(MonitorHMP *hmp, const QDict *qdict)
     for (accel = info->present; accel; accel = accel->next) {
         char trail = accel->next ? ' ' : '\n';
         if (info->enabled == accel->value) {
-            monitor_printf(mon, "[%s]%c", Accelerator_str(accel->value), trail);
+            monitor_hmp_printf(hmp, "[%s]%c", Accelerator_str(accel->value), trail);
         } else {
-            monitor_printf(mon, "%s%c", Accelerator_str(accel->value), trail);
+            monitor_hmp_printf(hmp, "%s%c", Accelerator_str(accel->value), trail);
         }
     }
 
@@ -187,17 +182,15 @@ void hmp_info_accelerators(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_uuid(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     UuidInfo *info;
 
     info = qmp_query_uuid(NULL);
-    monitor_printf(mon, "%s\n", info->UUID);
+    monitor_hmp_printf(hmp, "%s\n", info->UUID);
     qapi_free_UuidInfo(info);
 }
 
 void hmp_info_balloon(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     BalloonInfo *info;
     Error *err = NULL;
 
@@ -206,7 +199,7 @@ void hmp_info_balloon(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
+    monitor_hmp_printf(hmp, "balloon: actual=%" PRId64 "\n", info->actual >> 20);
 
     qapi_free_BalloonInfo(info);
 }
@@ -223,7 +216,6 @@ void hmp_system_powerdown(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_memsave(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     uint32_t size = qdict_get_int(qdict, "size");
     const char *filename = qdict_get_str(qdict, "filename");
     uint64_t addr = qdict_get_int(qdict, "val");
@@ -231,7 +223,7 @@ void hmp_memsave(MonitorHMP *hmp, const QDict *qdict)
     int cpu_index = monitor_hmp_get_cpu_index(hmp);
 
     if (cpu_index < 0) {
-        monitor_printf(mon, "No CPU available\n");
+        monitor_hmp_printf(hmp, "No CPU available\n");
         return;
     }
 
@@ -277,7 +269,6 @@ void hmp_balloon(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_memory_devices(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err);
     MemoryDeviceInfoList *info;
@@ -298,76 +289,76 @@ void hmp_info_memory_devices(MonitorHMP *hmp, const QDict *qdict)
             case MEMORY_DEVICE_INFO_KIND_NVDIMM:
                 di = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ?
                      value->u.dimm.data : value->u.nvdimm.data;
-                monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
-                               MemoryDeviceInfoKind_str(value->type),
-                               di->id ? di->id : "");
-                monitor_printf(mon, "  addr: 0x%" PRIx64 "\n", di->addr);
-                monitor_printf(mon, "  slot: %" PRId64 "\n", di->slot);
-                monitor_printf(mon, "  node: %" PRId64 "\n", di->node);
-                monitor_printf(mon, "  size: %" PRIu64 "\n", di->size);
-                monitor_printf(mon, "  memdev: %s\n", di->memdev);
-                monitor_printf(mon, "  hotplugged: %s\n",
-                               di->hotplugged ? "true" : "false");
-                monitor_printf(mon, "  hotpluggable: %s\n",
-                               di->hotpluggable ? "true" : "false");
+                monitor_hmp_printf(hmp, "Memory device [%s]: \"%s\"\n",
+                                   MemoryDeviceInfoKind_str(value->type),
+                                   di->id ? di->id : "");
+                monitor_hmp_printf(hmp, "  addr: 0x%" PRIx64 "\n", di->addr);
+                monitor_hmp_printf(hmp, "  slot: %" PRId64 "\n", di->slot);
+                monitor_hmp_printf(hmp, "  node: %" PRId64 "\n", di->node);
+                monitor_hmp_printf(hmp, "  size: %" PRIu64 "\n", di->size);
+                monitor_hmp_printf(hmp, "  memdev: %s\n", di->memdev);
+                monitor_hmp_printf(hmp, "  hotplugged: %s\n",
+                                   di->hotplugged ? "true" : "false");
+                monitor_hmp_printf(hmp, "  hotpluggable: %s\n",
+                                   di->hotpluggable ? "true" : "false");
                 break;
             case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM:
                 vpi = value->u.virtio_pmem.data;
-                monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
-                               MemoryDeviceInfoKind_str(value->type),
-                               vpi->id ? vpi->id : "");
-                monitor_printf(mon, "  memaddr: 0x%" PRIx64 "\n", vpi->memaddr);
-                monitor_printf(mon, "  size: %" PRIu64 "\n", vpi->size);
-                monitor_printf(mon, "  memdev: %s\n", vpi->memdev);
+                monitor_hmp_printf(hmp, "Memory device [%s]: \"%s\"\n",
+                                   MemoryDeviceInfoKind_str(value->type),
+                                   vpi->id ? vpi->id : "");
+                monitor_hmp_printf(hmp, "  memaddr: 0x%" PRIx64 "\n", vpi->memaddr);
+                monitor_hmp_printf(hmp, "  size: %" PRIu64 "\n", vpi->size);
+                monitor_hmp_printf(hmp, "  memdev: %s\n", vpi->memdev);
                 break;
             case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM:
                 vmi = value->u.virtio_mem.data;
-                monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
-                               MemoryDeviceInfoKind_str(value->type),
-                               vmi->id ? vmi->id : "");
-                monitor_printf(mon, "  memaddr: 0x%" PRIx64 "\n", vmi->memaddr);
-                monitor_printf(mon, "  node: %" PRId64 "\n", vmi->node);
-                monitor_printf(mon, "  requested-size: %" PRIu64 "\n",
-                               vmi->requested_size);
-                monitor_printf(mon, "  size: %" PRIu64 "\n", vmi->size);
-                monitor_printf(mon, "  max-size: %" PRIu64 "\n", vmi->max_size);
-                monitor_printf(mon, "  block-size: %" PRIu64 "\n",
-                               vmi->block_size);
-                monitor_printf(mon, "  memdev: %s\n", vmi->memdev);
+                monitor_hmp_printf(hmp, "Memory device [%s]: \"%s\"\n",
+                                   MemoryDeviceInfoKind_str(value->type),
+                                   vmi->id ? vmi->id : "");
+                monitor_hmp_printf(hmp, "  memaddr: 0x%" PRIx64 "\n", vmi->memaddr);
+                monitor_hmp_printf(hmp, "  node: %" PRId64 "\n", vmi->node);
+                monitor_hmp_printf(hmp, "  requested-size: %" PRIu64 "\n",
+                                   vmi->requested_size);
+                monitor_hmp_printf(hmp, "  size: %" PRIu64 "\n", vmi->size);
+                monitor_hmp_printf(hmp, "  max-size: %" PRIu64 "\n", vmi->max_size);
+                monitor_hmp_printf(hmp, "  block-size: %" PRIu64 "\n",
+                                   vmi->block_size);
+                monitor_hmp_printf(hmp, "  memdev: %s\n", vmi->memdev);
                 break;
             case MEMORY_DEVICE_INFO_KIND_SGX_EPC:
                 se = value->u.sgx_epc.data;
-                monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
-                               MemoryDeviceInfoKind_str(value->type),
-                               se->id ? se->id : "");
-                monitor_printf(mon, "  memaddr: 0x%" PRIx64 "\n", se->memaddr);
-                monitor_printf(mon, "  size: %" PRIu64 "\n", se->size);
-                monitor_printf(mon, "  node: %" PRId64 "\n", se->node);
-                monitor_printf(mon, "  memdev: %s\n", se->memdev);
+                monitor_hmp_printf(hmp, "Memory device [%s]: \"%s\"\n",
+                                   MemoryDeviceInfoKind_str(value->type),
+                                   se->id ? se->id : "");
+                monitor_hmp_printf(hmp, "  memaddr: 0x%" PRIx64 "\n", se->memaddr);
+                monitor_hmp_printf(hmp, "  size: %" PRIu64 "\n", se->size);
+                monitor_hmp_printf(hmp, "  node: %" PRId64 "\n", se->node);
+                monitor_hmp_printf(hmp, "  memdev: %s\n", se->memdev);
                 break;
             case MEMORY_DEVICE_INFO_KIND_HV_BALLOON:
                 hi = value->u.hv_balloon.data;
-                monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
-                               MemoryDeviceInfoKind_str(value->type),
-                               hi->id ? hi->id : "");
+                monitor_hmp_printf(hmp, "Memory device [%s]: \"%s\"\n",
+                                   MemoryDeviceInfoKind_str(value->type),
+                                   hi->id ? hi->id : "");
                 if (hi->has_memaddr) {
-                    monitor_printf(mon, "  memaddr: 0x%" PRIx64 "\n",
-                                   hi->memaddr);
+                    monitor_hmp_printf(hmp, "  memaddr: 0x%" PRIx64 "\n",
+                                       hi->memaddr);
                 }
-                monitor_printf(mon, "  max-size: %" PRIu64 "\n", hi->max_size);
+                monitor_hmp_printf(hmp, "  max-size: %" PRIu64 "\n", hi->max_size);
                 if (hi->memdev) {
-                    monitor_printf(mon, "  memdev: %s\n", hi->memdev);
+                    monitor_hmp_printf(hmp, "  memdev: %s\n", hi->memdev);
                 }
                 break;
             case MEMORY_DEVICE_INFO_KIND_SP_MEM:
                 spmi = value->u.sp_mem.data;
-                monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
-                               MemoryDeviceInfoKind_str(value->type),
-                               spmi->id ? spmi->id : "");
-                monitor_printf(mon, "  addr: 0x%" PRIx64 "\n", spmi->addr);
-                monitor_printf(mon, "  node: %" PRId64 "\n", spmi->node);
-                monitor_printf(mon, "  size: %" PRIu64 "\n", spmi->size);
-                monitor_printf(mon, "  memdev: %s\n", spmi->memdev);
+                monitor_hmp_printf(hmp, "Memory device [%s]: \"%s\"\n",
+                                   MemoryDeviceInfoKind_str(value->type),
+                                   spmi->id ? spmi->id : "");
+                monitor_hmp_printf(hmp, "  addr: 0x%" PRIx64 "\n", spmi->addr);
+                monitor_hmp_printf(hmp, "  node: %" PRId64 "\n", spmi->node);
+                monitor_hmp_printf(hmp, "  size: %" PRIu64 "\n", spmi->size);
+                monitor_hmp_printf(hmp, "  memdev: %s\n", spmi->memdev);
                 break;
             default:
                 g_assert_not_reached();
@@ -381,11 +372,10 @@ void hmp_info_memory_devices(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_vm_generation_id(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     GuidInfo *info = qmp_query_vm_generation_id(&err);
     if (info) {
-        monitor_printf(mon, "%s\n", info->guid);
+        monitor_hmp_printf(hmp, "%s\n", info->guid);
     }
     hmp_handle_error(hmp, err);
     qapi_free_GuidInfo(info);
@@ -393,16 +383,15 @@ void hmp_info_vm_generation_id(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_memory_size_summary(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     MemoryInfo *info = qmp_query_memory_size_summary(&err);
     if (info) {
-        monitor_printf(mon, "base memory: %" PRIu64 "\n",
-                       info->base_memory);
+        monitor_hmp_printf(hmp, "base memory: %" PRIu64 "\n",
+                           info->base_memory);
 
         if (info->has_plugged_memory) {
-            monitor_printf(mon, "plugged memory: %" PRIu64 "\n",
-                           info->plugged_memory);
+            monitor_hmp_printf(hmp, "plugged memory: %" PRIu64 "\n",
+                               info->plugged_memory);
         }
 
         qapi_free_MemoryInfo(info);
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 13df7cbafe10..82130ba04698 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -252,13 +252,14 @@ bool sysbus_realize_and_unref(SysBusDevice *dev, Error **errp)
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent)
 {
     SysBusDevice *s = SYS_BUS_DEVICE(dev);
+    MonitorHMP *hmp = MONITOR_HMP(mon);
     hwaddr size;
     int i;
 
     for (i = 0; i < s->num_mmio; i++) {
         size = memory_region_size(s->mmio[i].memory);
-        monitor_printf(mon, "%*smmio " HWADDR_FMT_plx "/" HWADDR_FMT_plx "\n",
-                       indent, "", s->mmio[i].addr, size);
+        monitor_hmp_printf(hmp, "%*smmio " HWADDR_FMT_plx "/" HWADDR_FMT_plx "\n",
+                           indent, "", s->mmio[i].addr, size);
     }
 }
 
diff --git a/hw/hexagon/hexagon_tlb.c b/hw/hexagon/hexagon_tlb.c
index 2d878cee736d..576929ff224b 100644
--- a/hw/hexagon/hexagon_tlb.c
+++ b/hw/hexagon/hexagon_tlb.c
@@ -124,30 +124,32 @@ static inline uint64_t hex_tlb_virt_addr(uint64_t entry)
 
 bool hexagon_tlb_dump_entry(Monitor *mon, uint64_t entry)
 {
+    MonitorHMP *hmp = MONITOR_HMP(mon);
+
     if (GET_PTE_V(entry)) {
         uint64_t PA = hex_tlb_phys_addr(entry);
         uint64_t VA = hex_tlb_virt_addr(entry);
-        monitor_printf(mon, "0x%016" PRIx64 ": ", entry);
-        monitor_printf(mon, "V:%" PRId64 " G:%" PRId64
-                       " A1:%" PRId64 " A0:%" PRId64,
-                       GET_PTE_V(entry),
-                       GET_PTE_G(entry),
-                       GET_PTE_ATR1(entry),
-                       GET_PTE_ATR0(entry));
-        monitor_printf(mon, " ASID:0x%02" PRIx64 " VA:0x%08" PRIx64,
-                       GET_PTE_ASID(entry), VA);
-        monitor_printf(mon,
-                       " X:%" PRId64 " W:%" PRId64 " R:%" PRId64
-                       " U:%" PRId64 " C:%" PRId64,
-                       GET_PTE_X(entry),
-                       GET_PTE_W(entry),
-                       GET_PTE_R(entry),
-                       GET_PTE_U(entry),
-                       GET_PTE_C(entry));
-        monitor_printf(mon, " PA:0x%09" PRIx64 " SZ:%s (0x%" PRIx64 ")",
-                       PA, pgsize_str[hex_tlb_pgsize_type(entry)],
-                       hex_tlb_page_size_bytes(entry));
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "0x%016" PRIx64 ": ", entry);
+        monitor_hmp_printf(hmp, "V:%" PRId64 " G:%" PRId64
+                           " A1:%" PRId64 " A0:%" PRId64,
+                           GET_PTE_V(entry),
+                           GET_PTE_G(entry),
+                           GET_PTE_ATR1(entry),
+                           GET_PTE_ATR0(entry));
+        monitor_hmp_printf(hmp, " ASID:0x%02" PRIx64 " VA:0x%08" PRIx64,
+                           GET_PTE_ASID(entry), VA);
+        monitor_hmp_printf(hmp,
+                           " X:%" PRId64 " W:%" PRId64 " R:%" PRId64
+                           " U:%" PRId64 " C:%" PRId64,
+                           GET_PTE_X(entry),
+                           GET_PTE_W(entry),
+                           GET_PTE_R(entry),
+                           GET_PTE_U(entry),
+                           GET_PTE_C(entry));
+        monitor_hmp_printf(hmp, " PA:0x%09" PRIx64 " SZ:%s (0x%" PRIx64 ")",
+                           PA, pgsize_str[hex_tlb_pgsize_type(entry)],
+                           hex_tlb_page_size_bytes(entry));
+        monitor_hmp_printf(hmp, "\n");
         return true;
     }
 
diff --git a/hw/i386/kvm/xen-stubs.c b/hw/i386/kvm/xen-stubs.c
index ab1eb14f99e0..5ed71583281a 100644
--- a/hw/i386/kvm/xen-stubs.c
+++ b/hw/i386/kvm/xen-stubs.c
@@ -42,12 +42,10 @@ void xen_primary_console_set_be_port(uint16_t port)
 
 void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
-    monitor_printf(mon, "XEN emulation is not available in this QEMU\n");
+    monitor_hmp_printf(hmp, "XEN emulation is not available in this QEMU\n");
 }
 
 void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
-    monitor_printf(mon, "XEN emulation is not available in this QEMU\n");
+    monitor_hmp_printf(hmp, "XEN emulation is not available in this QEMU\n");
 }
diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c
index 00dff6ee8760..b2135020f27f 100644
--- a/hw/i386/kvm/xen_evtchn.c
+++ b/hw/i386/kvm/xen_evtchn.c
@@ -2346,7 +2346,6 @@ void qmp_xen_event_inject(uint32_t port, Error **errp)
 
 void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     EvtchnInfoList *iter, *info_list;
     Error *err = NULL;
 
@@ -2359,22 +2358,22 @@ void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict)
     for (iter = info_list; iter; iter = iter->next) {
         EvtchnInfo *info = iter->value;
 
-        monitor_printf(mon, "port %4u: vcpu: %d %s", info->port, info->vcpu,
-                       EvtchnPortType_str(info->type));
+        monitor_hmp_printf(hmp, "port %4u: vcpu: %d %s", info->port, info->vcpu,
+                           EvtchnPortType_str(info->type));
         if (info->type != EVTCHN_PORT_TYPE_IPI) {
-            monitor_printf(mon,  "(");
+            monitor_hmp_printf(hmp,  "(");
             if (info->remote_domain) {
-                monitor_printf(mon, "%s:", info->remote_domain);
+                monitor_hmp_printf(hmp, "%s:", info->remote_domain);
             }
-            monitor_printf(mon, "%d)", info->target);
+            monitor_hmp_printf(hmp, "%d)", info->target);
         }
         if (info->pending) {
-            monitor_printf(mon, " PENDING");
+            monitor_hmp_printf(hmp, " PENDING");
         }
         if (info->masked) {
-            monitor_printf(mon, " MASKED");
+            monitor_hmp_printf(hmp, " MASKED");
         }
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "\n");
     }
 
     qapi_free_EvtchnInfoList(info_list);
@@ -2382,7 +2381,6 @@ void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int port = qdict_get_int(qdict, "port");
     Error *err = NULL;
 
@@ -2390,7 +2388,6 @@ void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict)
     if (err) {
         hmp_handle_error(hmp, err);
     } else {
-        monitor_printf(mon, "Delivered port %d\n", port);
+        monitor_hmp_printf(hmp, "Delivered port %d\n", port);
     }
 }
-
diff --git a/hw/i386/sgx-hmp-stub.c b/hw/i386/sgx-hmp-stub.c
index a4848ae1d1a7..b7afb26886a8 100644
--- a/hw/i386/sgx-hmp-stub.c
+++ b/hw/i386/sgx-hmp-stub.c
@@ -12,6 +12,5 @@
 
 void hmp_info_sgx(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
-    monitor_printf(mon, "SGX is not available in this QEMU\n");
+    monitor_hmp_printf(hmp, "SGX is not available in this QEMU\n");
 }
diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
index 77b41d234c9f..634e33e819ce 100644
--- a/hw/i386/sgx.c
+++ b/hw/i386/sgx.c
@@ -236,7 +236,6 @@ SgxInfo *qmp_query_sgx(Error **errp)
 
 void hmp_info_sgx(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     SgxEpcSectionList *section_list, *section;
     g_autoptr(SgxInfo) info = qmp_query_sgx(&err);
@@ -246,25 +245,25 @@ void hmp_info_sgx(MonitorHMP *hmp, const QDict *qdict)
         error_report_err(err);
         return;
     }
-    monitor_printf(mon, "SGX support: %s\n",
-                   info->sgx ? "enabled" : "disabled");
-    monitor_printf(mon, "SGX1 support: %s\n",
-                   info->sgx1 ? "enabled" : "disabled");
-    monitor_printf(mon, "SGX2 support: %s\n",
-                   info->sgx2 ? "enabled" : "disabled");
-    monitor_printf(mon, "FLC support: %s\n",
-                   info->flc ? "enabled" : "disabled");
+    monitor_hmp_printf(hmp, "SGX support: %s\n",
+                       info->sgx ? "enabled" : "disabled");
+    monitor_hmp_printf(hmp, "SGX1 support: %s\n",
+                       info->sgx1 ? "enabled" : "disabled");
+    monitor_hmp_printf(hmp, "SGX2 support: %s\n",
+                       info->sgx2 ? "enabled" : "disabled");
+    monitor_hmp_printf(hmp, "FLC support: %s\n",
+                       info->flc ? "enabled" : "disabled");
 
     section_list = info->sections;
     for (section = section_list; section; section = section->next) {
-        monitor_printf(mon, "NUMA node #%" PRId64 ": ",
-                       section->value->node);
-        monitor_printf(mon, "size=%" PRIu64 "\n",
-                       section->value->size);
+        monitor_hmp_printf(hmp, "NUMA node #%" PRId64 ": ",
+                           section->value->node);
+        monitor_hmp_printf(hmp, "size=%" PRIu64 "\n",
+                           section->value->size);
         size += section->value->size;
     }
-    monitor_printf(mon, "total size=%" PRIu64 "\n",
-                   size);
+    monitor_hmp_printf(hmp, "total size=%" PRIu64 "\n",
+                       size);
 }
 
 bool check_sgx_support(void)
diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
index ac2525b90fec..ffa76f83016b 100644
--- a/hw/misc/auxbus.c
+++ b/hw/misc/auxbus.c
@@ -300,10 +300,11 @@ static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent)
 
     s = AUX_SLAVE(dev);
 
-    monitor_printf(mon, "%*smemory " HWADDR_FMT_plx "/" HWADDR_FMT_plx "\n",
-                   indent, "",
-                   object_property_get_uint(OBJECT(s->mmio), "addr", NULL),
-                   memory_region_size(s->mmio));
+    monitor_hmp_printf(MONITOR_HMP(mon),
+                       "%*smemory " HWADDR_FMT_plx "/" HWADDR_FMT_plx "\n",
+                       indent, "",
+                       object_property_get_uint(OBJECT(s->mmio), "addr", NULL),
+                       memory_region_size(s->mmio));
 }
 
 void aux_init_mmio(AUXSlave *aux_slave, MemoryRegion *mmio)
diff --git a/hw/misc/mos6522-stub.c b/hw/misc/mos6522-stub.c
index 6a7d76292f00..154cd32ed88b 100644
--- a/hw/misc/mos6522-stub.c
+++ b/hw/misc/mos6522-stub.c
@@ -12,6 +12,5 @@
 
 void hmp_info_via(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
-    monitor_printf(mon, "MOS6522 VIA is not available in this QEMU\n");
+    monitor_hmp_printf(hmp, "MOS6522 VIA is not available in this QEMU\n");
 }
diff --git a/hw/net/rocker/rocker-hmp-cmds.c b/hw/net/rocker/rocker-hmp-cmds.c
index 6405ce26dd65..5099d59cc620 100644
--- a/hw/net/rocker/rocker-hmp-cmds.c
+++ b/hw/net/rocker/rocker-hmp-cmds.c
@@ -22,7 +22,6 @@
 
 void hmp_rocker(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *name = qdict_get_str(qdict, "name");
     RockerSwitch *rocker;
     Error *err = NULL;
@@ -32,16 +31,15 @@ void hmp_rocker(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "name: %s\n", rocker->name);
-    monitor_printf(mon, "id: 0x%" PRIx64 "\n", rocker->id);
-    monitor_printf(mon, "ports: %d\n", rocker->ports);
+    monitor_hmp_printf(hmp, "name: %s\n", rocker->name);
+    monitor_hmp_printf(hmp, "id: 0x%" PRIx64 "\n", rocker->id);
+    monitor_hmp_printf(hmp, "ports: %d\n", rocker->ports);
 
     qapi_free_RockerSwitch(rocker);
 }
 
 void hmp_rocker_ports(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     RockerPortList *list, *port;
     const char *name = qdict_get_str(qdict, "name");
     Error *err = NULL;
@@ -51,17 +49,17 @@ void hmp_rocker_ports(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "            ena/    speed/ auto\n");
-    monitor_printf(mon, "      port  link    duplex neg?\n");
+    monitor_hmp_printf(hmp, "            ena/    speed/ auto\n");
+    monitor_hmp_printf(hmp, "      port  link    duplex neg?\n");
 
     for (port = list; port; port = port->next) {
-        monitor_printf(mon, "%10s  %-4s   %-3s  %2s  %s\n",
-                       port->value->name,
-                       port->value->enabled ? port->value->link_up ?
-                       "up" : "down" : "!ena",
-                       port->value->speed == 10000 ? "10G" : "??",
-                       port->value->duplex ? "FD" : "HD",
-                       port->value->autoneg ? "Yes" : "No");
+        monitor_hmp_printf(hmp, "%10s  %-4s   %-3s  %2s  %s\n",
+                           port->value->name,
+                           port->value->enabled ? port->value->link_up ?
+                           "up" : "down" : "!ena",
+                           port->value->speed == 10000 ? "10G" : "??",
+                           port->value->duplex ? "FD" : "HD",
+                           port->value->autoneg ? "Yes" : "No");
     }
 
     qapi_free_RockerPortList(list);
@@ -69,7 +67,6 @@ void hmp_rocker_ports(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_rocker_of_dpa_flows(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     RockerOfDpaFlowList *list, *info;
     const char *name = qdict_get_str(qdict, "name");
     uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1);
@@ -80,7 +77,7 @@ void hmp_rocker_of_dpa_flows(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "prio tbl hits key(mask) --> actions\n");
+    monitor_hmp_printf(hmp, "prio tbl hits key(mask) --> actions\n");
 
     for (info = list; info; info = info->next) {
         RockerOfDpaFlow *flow = info->value;
@@ -89,54 +86,54 @@ void hmp_rocker_of_dpa_flows(MonitorHMP *hmp, const QDict *qdict)
         RockerOfDpaFlowAction *action = flow->action;
 
         if (flow->hits) {
-            monitor_printf(mon, "%-4d %-3d %-4" PRIu64,
-                           key->priority, key->tbl_id, flow->hits);
+            monitor_hmp_printf(hmp, "%-4d %-3d %-4" PRIu64,
+                               key->priority, key->tbl_id, flow->hits);
         } else {
-            monitor_printf(mon, "%-4d %-3d     ",
-                           key->priority, key->tbl_id);
+            monitor_hmp_printf(hmp, "%-4d %-3d     ",
+                               key->priority, key->tbl_id);
         }
 
         if (key->has_in_pport) {
-            monitor_printf(mon, " pport %d", key->in_pport);
+            monitor_hmp_printf(hmp, " pport %d", key->in_pport);
             if (mask->has_in_pport) {
-                monitor_printf(mon, "(0x%x)", mask->in_pport);
+                monitor_hmp_printf(hmp, "(0x%x)", mask->in_pport);
             }
         }
 
         if (key->has_vlan_id) {
-            monitor_printf(mon, " vlan %d",
-                           key->vlan_id & VLAN_VID_MASK);
+            monitor_hmp_printf(hmp, " vlan %d",
+                               key->vlan_id & VLAN_VID_MASK);
             if (mask->has_vlan_id) {
-                monitor_printf(mon, "(0x%x)", mask->vlan_id);
+                monitor_hmp_printf(hmp, "(0x%x)", mask->vlan_id);
             }
         }
 
         if (key->has_tunnel_id) {
-            monitor_printf(mon, " tunnel %d", key->tunnel_id);
+            monitor_hmp_printf(hmp, " tunnel %d", key->tunnel_id);
             if (mask->has_tunnel_id) {
-                monitor_printf(mon, "(0x%x)", mask->tunnel_id);
+                monitor_hmp_printf(hmp, "(0x%x)", mask->tunnel_id);
             }
         }
 
         if (key->has_eth_type) {
             switch (key->eth_type) {
             case 0x0806:
-                monitor_printf(mon, " ARP");
+                monitor_hmp_printf(hmp, " ARP");
                 break;
             case 0x0800:
-                monitor_printf(mon, " IP");
+                monitor_hmp_printf(hmp, " IP");
                 break;
             case 0x86dd:
-                monitor_printf(mon, " IPv6");
+                monitor_hmp_printf(hmp, " IPv6");
                 break;
             case 0x8809:
-                monitor_printf(mon, " LACP");
+                monitor_hmp_printf(hmp, " LACP");
                 break;
             case 0x88cc:
-                monitor_printf(mon, " LLDP");
+                monitor_hmp_printf(hmp, " LLDP");
                 break;
             default:
-                monitor_printf(mon, " eth type 0x%04x", key->eth_type);
+                monitor_hmp_printf(hmp, " eth type 0x%04x", key->eth_type);
                 break;
             }
         }
@@ -145,15 +142,15 @@ void hmp_rocker_of_dpa_flows(MonitorHMP *hmp, const QDict *qdict)
             if ((strcmp(key->eth_src, "01:00:00:00:00:00") == 0) &&
                 mask->eth_src &&
                 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
-                monitor_printf(mon, " src <any mcast/bcast>");
+                monitor_hmp_printf(hmp, " src <any mcast/bcast>");
             } else if ((strcmp(key->eth_src, "00:00:00:00:00:00") == 0) &&
                 mask->eth_src &&
                 (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) {
-                monitor_printf(mon, " src <any ucast>");
+                monitor_hmp_printf(hmp, " src <any ucast>");
             } else {
-                monitor_printf(mon, " src %s", key->eth_src);
+                monitor_hmp_printf(hmp, " src %s", key->eth_src);
                 if (mask->eth_src) {
-                    monitor_printf(mon, "(%s)", mask->eth_src);
+                    monitor_hmp_printf(hmp, "(%s)", mask->eth_src);
                 }
             }
         }
@@ -162,56 +159,56 @@ void hmp_rocker_of_dpa_flows(MonitorHMP *hmp, const QDict *qdict)
             if ((strcmp(key->eth_dst, "01:00:00:00:00:00") == 0) &&
                 mask->eth_dst &&
                 (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
-                monitor_printf(mon, " dst <any mcast/bcast>");
+                monitor_hmp_printf(hmp, " dst <any mcast/bcast>");
             } else if ((strcmp(key->eth_dst, "00:00:00:00:00:00") == 0) &&
                 mask->eth_dst &&
                 (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) {
-                monitor_printf(mon, " dst <any ucast>");
+                monitor_hmp_printf(hmp, " dst <any ucast>");
             } else {
-                monitor_printf(mon, " dst %s", key->eth_dst);
+                monitor_hmp_printf(hmp, " dst %s", key->eth_dst);
                 if (mask->eth_dst) {
-                    monitor_printf(mon, "(%s)", mask->eth_dst);
+                    monitor_hmp_printf(hmp, "(%s)", mask->eth_dst);
                 }
             }
         }
 
         if (key->has_ip_proto) {
-            monitor_printf(mon, " proto %d", key->ip_proto);
+            monitor_hmp_printf(hmp, " proto %d", key->ip_proto);
             if (mask->has_ip_proto) {
-                monitor_printf(mon, "(0x%x)", mask->ip_proto);
+                monitor_hmp_printf(hmp, "(0x%x)", mask->ip_proto);
             }
         }
 
         if (key->has_ip_tos) {
-            monitor_printf(mon, " TOS %d", key->ip_tos);
+            monitor_hmp_printf(hmp, " TOS %d", key->ip_tos);
             if (mask->has_ip_tos) {
-                monitor_printf(mon, "(0x%x)", mask->ip_tos);
+                monitor_hmp_printf(hmp, "(0x%x)", mask->ip_tos);
             }
         }
 
         if (key->ip_dst) {
-            monitor_printf(mon, " dst %s", key->ip_dst);
+            monitor_hmp_printf(hmp, " dst %s", key->ip_dst);
         }
 
         if (action->has_goto_tbl || action->has_group_id ||
             action->has_new_vlan_id) {
-            monitor_printf(mon, " -->");
+            monitor_hmp_printf(hmp, " -->");
         }
 
         if (action->has_new_vlan_id) {
-            monitor_printf(mon, " apply new vlan %d",
-                           ntohs(action->new_vlan_id));
+            monitor_hmp_printf(hmp, " apply new vlan %d",
+                               ntohs(action->new_vlan_id));
         }
 
         if (action->has_group_id) {
-            monitor_printf(mon, " write group 0x%08x", action->group_id);
+            monitor_hmp_printf(hmp, " write group 0x%08x", action->group_id);
         }
 
         if (action->has_goto_tbl) {
-            monitor_printf(mon, " goto tbl %d", action->goto_tbl);
+            monitor_hmp_printf(hmp, " goto tbl %d", action->goto_tbl);
         }
 
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "\n");
     }
 
     qapi_free_RockerOfDpaFlowList(list);
@@ -219,7 +216,6 @@ void hmp_rocker_of_dpa_flows(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_rocker_of_dpa_groups(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     RockerOfDpaGroupList *list, *g;
     const char *name = qdict_get_str(qdict, "name");
     uint8_t type = qdict_get_try_int(qdict, "type", 9);
@@ -230,15 +226,15 @@ void hmp_rocker_of_dpa_groups(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "id (decode) --> buckets\n");
+    monitor_hmp_printf(hmp, "id (decode) --> buckets\n");
 
     for (g = list; g; g = g->next) {
         RockerOfDpaGroup *group = g->value;
         bool set = false;
 
-        monitor_printf(mon, "0x%08x", group->id);
+        monitor_hmp_printf(hmp, "0x%08x", group->id);
 
-        monitor_printf(mon, " (type %s", group->type == 0 ? "L2 interface" :
+        monitor_hmp_printf(hmp, " (type %s", group->type == 0 ? "L2 interface" :
                                          group->type == 1 ? "L2 rewrite" :
                                          group->type == 2 ? "L3 unicast" :
                                          group->type == 3 ? "L2 multicast" :
@@ -250,70 +246,70 @@ void hmp_rocker_of_dpa_groups(MonitorHMP *hmp, const QDict *qdict)
                                          "unknown");
 
         if (group->has_vlan_id) {
-            monitor_printf(mon, " vlan %d", group->vlan_id);
+            monitor_hmp_printf(hmp, " vlan %d", group->vlan_id);
         }
 
         if (group->has_pport) {
-            monitor_printf(mon, " pport %d", group->pport);
+            monitor_hmp_printf(hmp, " pport %d", group->pport);
         }
 
         if (group->has_index) {
-            monitor_printf(mon, " index %d", group->index);
+            monitor_hmp_printf(hmp, " index %d", group->index);
         }
 
-        monitor_printf(mon, ") -->");
+        monitor_hmp_printf(hmp, ") -->");
 
         if (group->has_set_vlan_id && group->set_vlan_id) {
             set = true;
-            monitor_printf(mon, " set vlan %d",
-                           group->set_vlan_id & VLAN_VID_MASK);
+            monitor_hmp_printf(hmp, " set vlan %d",
+                               group->set_vlan_id & VLAN_VID_MASK);
         }
 
         if (group->set_eth_src) {
             if (!set) {
                 set = true;
-                monitor_printf(mon, " set");
+                monitor_hmp_printf(hmp, " set");
             }
-            monitor_printf(mon, " src %s", group->set_eth_src);
+            monitor_hmp_printf(hmp, " src %s", group->set_eth_src);
         }
 
         if (group->set_eth_dst) {
             if (!set) {
-                monitor_printf(mon, " set");
+                monitor_hmp_printf(hmp, " set");
             }
-            monitor_printf(mon, " dst %s", group->set_eth_dst);
+            monitor_hmp_printf(hmp, " dst %s", group->set_eth_dst);
         }
 
         if (group->has_ttl_check && group->ttl_check) {
-            monitor_printf(mon, " check TTL");
+            monitor_hmp_printf(hmp, " check TTL");
         }
 
         if (group->has_group_id && group->group_id) {
-            monitor_printf(mon, " group id 0x%08x", group->group_id);
+            monitor_hmp_printf(hmp, " group id 0x%08x", group->group_id);
         }
 
         if (group->has_pop_vlan && group->pop_vlan) {
-            monitor_printf(mon, " pop vlan");
+            monitor_hmp_printf(hmp, " pop vlan");
         }
 
         if (group->has_out_pport) {
-            monitor_printf(mon, " out pport %d", group->out_pport);
+            monitor_hmp_printf(hmp, " out pport %d", group->out_pport);
         }
 
         if (group->has_group_ids) {
             struct uint32List *id;
 
-            monitor_printf(mon, " groups [");
+            monitor_hmp_printf(hmp, " groups [");
             for (id = group->group_ids; id; id = id->next) {
-                monitor_printf(mon, "0x%08x", id->value);
+                monitor_hmp_printf(hmp, "0x%08x", id->value);
                 if (id->next) {
-                    monitor_printf(mon, ",");
+                    monitor_hmp_printf(hmp, ",");
                 }
             }
-            monitor_printf(mon, "]");
+            monitor_hmp_printf(hmp, "]");
         }
 
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "\n");
     }
 
     qapi_free_RockerOfDpaGroupList(list);
diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c
index 51d95d76620e..500f821246a9 100644
--- a/hw/pci/pci-hmp-cmds.c
+++ b/hw/pci/pci-hmp-cmds.c
@@ -24,54 +24,55 @@
 #include "qapi/qapi-commands-pci.h"
 #include "qemu/cutils.h"
 
-static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
+static void hmp_info_pci_device(MonitorHMP *hmp, const PciDeviceInfo *dev)
 {
+    Monitor *mon = MONITOR(hmp);
     PciMemoryRegionList *region;
 
-    monitor_printf(mon, "  Bus %2" PRId64 ", ", dev->bus);
-    monitor_printf(mon, "device %3" PRId64 ", function %" PRId64 ":\n",
-                   dev->slot, dev->function);
-    monitor_printf(mon, "    ");
+    monitor_hmp_printf(hmp, "  Bus %2" PRId64 ", ", dev->bus);
+    monitor_hmp_printf(hmp, "device %3" PRId64 ", function %" PRId64 ":\n",
+                       dev->slot, dev->function);
+    monitor_hmp_printf(hmp, "    ");
 
     if (dev->class_info->desc) {
         monitor_puts(mon, dev->class_info->desc);
     } else {
-        monitor_printf(mon, "Class %04" PRId64, dev->class_info->q_class);
+        monitor_hmp_printf(hmp, "Class %04" PRId64, dev->class_info->q_class);
     }
 
-    monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
-                   dev->id->vendor, dev->id->device);
+    monitor_hmp_printf(hmp, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
+                       dev->id->vendor, dev->id->device);
     if (dev->id->has_subsystem_vendor && dev->id->has_subsystem) {
-        monitor_printf(mon, "      PCI subsystem %04" PRIx64 ":%04" PRIx64 "\n",
-                       dev->id->subsystem_vendor, dev->id->subsystem);
+        monitor_hmp_printf(hmp, "      PCI subsystem %04" PRIx64 ":%04" PRIx64 "\n",
+                           dev->id->subsystem_vendor, dev->id->subsystem);
     }
 
     if (dev->has_irq) {
-        monitor_printf(mon, "      IRQ %" PRId64 ", pin %c\n",
-                       dev->irq, (char)('A' + dev->irq_pin - 1));
+        monitor_hmp_printf(hmp, "      IRQ %" PRId64 ", pin %c\n",
+                           dev->irq, (char)('A' + dev->irq_pin - 1));
     }
 
     if (dev->pci_bridge) {
-        monitor_printf(mon, "      BUS %" PRId64 ".\n",
-                       dev->pci_bridge->bus->number);
-        monitor_printf(mon, "      secondary bus %" PRId64 ".\n",
-                       dev->pci_bridge->bus->secondary);
-        monitor_printf(mon, "      subordinate bus %" PRId64 ".\n",
-                       dev->pci_bridge->bus->subordinate);
+        monitor_hmp_printf(hmp, "      BUS %" PRId64 ".\n",
+                           dev->pci_bridge->bus->number);
+        monitor_hmp_printf(hmp, "      secondary bus %" PRId64 ".\n",
+                           dev->pci_bridge->bus->secondary);
+        monitor_hmp_printf(hmp, "      subordinate bus %" PRId64 ".\n",
+                           dev->pci_bridge->bus->subordinate);
 
-        monitor_printf(mon, "      IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n",
-                       dev->pci_bridge->bus->io_range->base,
-                       dev->pci_bridge->bus->io_range->limit);
+        monitor_hmp_printf(hmp, "      IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n",
+                           dev->pci_bridge->bus->io_range->base,
+                           dev->pci_bridge->bus->io_range->limit);
 
-        monitor_printf(mon,
-                       "      memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n",
-                       dev->pci_bridge->bus->memory_range->base,
-                       dev->pci_bridge->bus->memory_range->limit);
+        monitor_hmp_printf(hmp,
+                           "      memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n",
+                           dev->pci_bridge->bus->memory_range->base,
+                           dev->pci_bridge->bus->memory_range->limit);
 
-        monitor_printf(mon, "      prefetchable memory range "
-                       "[0x%08"PRIx64", 0x%08"PRIx64"]\n",
-                       dev->pci_bridge->bus->prefetchable_range->base,
-                       dev->pci_bridge->bus->prefetchable_range->limit);
+        monitor_hmp_printf(hmp, "      prefetchable memory range "
+                           "[0x%08"PRIx64", 0x%08"PRIx64"]\n",
+                           dev->pci_bridge->bus->prefetchable_range->base,
+                           dev->pci_bridge->bus->prefetchable_range->limit);
     }
 
     for (region = dev->regions; region; region = region->next) {
@@ -80,38 +81,38 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
         addr = region->value->address;
         size = region->value->size;
 
-        monitor_printf(mon, "      BAR%" PRId64 ": ", region->value->bar);
+        monitor_hmp_printf(hmp, "      BAR%" PRId64 ": ", region->value->bar);
 
         if (!strcmp(region->value->type, "io")) {
             if (addr != PCI_BAR_UNMAPPED) {
-                monitor_printf(mon, "I/O at 0x%04" PRIx64
+                monitor_hmp_printf(hmp, "I/O at 0x%04" PRIx64
                                     " [0x%04" PRIx64 "]\n",
                                addr, addr + size - 1);
             } else {
-                monitor_printf(mon, "I/O (not mapped)\n");
+                monitor_hmp_printf(hmp, "I/O (not mapped)\n");
             }
         } else {
             if (addr != PCI_BAR_UNMAPPED) {
-                monitor_printf(mon, "%d bit%s memory at 0x%08" PRIx64
+                monitor_hmp_printf(hmp, "%d bit%s memory at 0x%08" PRIx64
                                    " [0x%08" PRIx64 "]\n",
                                region->value->mem_type_64 ? 64 : 32,
                                region->value->prefetch ? " prefetchable" : "",
                                addr, addr + size - 1);
             } else {
-                monitor_printf(mon, "%d bit%s memory (not mapped)\n",
-                               region->value->mem_type_64 ? 64 : 32,
-                               region->value->prefetch ? " prefetchable" : "");
+                monitor_hmp_printf(hmp, "%d bit%s memory (not mapped)\n",
+                                   region->value->mem_type_64 ? 64 : 32,
+                                   region->value->prefetch ? " prefetchable" : "");
             }
         }
     }
 
-    monitor_printf(mon, "      id \"%s\"\n", dev->qdev_id);
+    monitor_hmp_printf(hmp, "      id \"%s\"\n", dev->qdev_id);
 
     if (dev->pci_bridge) {
         if (dev->pci_bridge->has_devices) {
             PciDeviceInfoList *cdev;
             for (cdev = dev->pci_bridge->devices; cdev; cdev = cdev->next) {
-                hmp_info_pci_device(mon, cdev->value);
+                hmp_info_pci_device(hmp, cdev->value);
             }
         }
     }
@@ -119,7 +120,6 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
 
 void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     PciInfoList *info_list, *info;
 
     info_list = qmp_query_pci(&error_abort);
@@ -128,7 +128,7 @@ void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict)
         PciDeviceInfoList *dev;
 
         for (dev = info->value->devices; dev; dev = dev->next) {
-            hmp_info_pci_device(mon, dev->value);
+            hmp_info_pci_device(hmp, dev->value);
         }
     }
 
@@ -137,6 +137,7 @@ void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict)
 
 void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
 {
+    MonitorHMP *hmp = MONITOR_HMP(mon);
     PCIDevice *d = (PCIDevice *)dev;
     int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
     const pci_class_desc *desc = get_class_desc(class);
@@ -150,30 +151,29 @@ void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
         snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
     }
 
-    monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
-                   "pci id %04x:%04x (sub %04x:%04x)\n",
-                   indent, "", ctxt, pci_dev_bus_num(d),
-                   PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
-                   pci_get_word(d->config + PCI_VENDOR_ID),
-                   pci_get_word(d->config + PCI_DEVICE_ID),
-                   pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID),
-                   pci_get_word(d->config + PCI_SUBSYSTEM_ID));
+    monitor_hmp_printf(hmp, "%*sclass %s, addr %02x:%02x.%x, "
+                       "pci id %04x:%04x (sub %04x:%04x)\n",
+                       indent, "", ctxt, pci_dev_bus_num(d),
+                       PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
+                       pci_get_word(d->config + PCI_VENDOR_ID),
+                       pci_get_word(d->config + PCI_DEVICE_ID),
+                       pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID),
+                       pci_get_word(d->config + PCI_SUBSYSTEM_ID));
     for (i = 0; i < PCI_NUM_REGIONS; i++) {
         r = &d->io_regions[i];
         if (!r->size) {
             continue;
         }
-        monitor_printf(mon, "%*sbar %d: %s at 0x%"FMT_PCIBUS
-                       " [0x%"FMT_PCIBUS"]\n",
-                       indent, "",
-                       i, r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
-                       r->addr, r->addr + r->size - 1);
+        monitor_hmp_printf(hmp, "%*sbar %d: %s at 0x%"FMT_PCIBUS
+                           " [0x%"FMT_PCIBUS"]\n",
+                           indent, "",
+                           i, r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
+                           r->addr, r->addr + r->size - 1);
     }
 }
 
 void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *id = qdict_get_str(qdict, "id");
     const char *error_name;
@@ -242,9 +242,9 @@ void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict)
     }
 
 
-    monitor_printf(mon, "OK id: %s root bus: %s, bus: %x devfn: %x.%x\n",
-                   id, pci_root_bus_path(dev), pci_dev_bus_num(dev),
-                   PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+    monitor_hmp_printf(hmp, "OK id: %s root bus: %s, bus: %x devfn: %x.%x\n",
+                       id, pci_root_bus_path(dev), pci_dev_bus_num(dev),
+                       PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
 
 out:
     hmp_handle_error(hmp, err);
diff --git a/hw/pci/pci-stub.c b/hw/pci/pci-stub.c
index a80e34175462..7e2797300ba0 100644
--- a/hw/pci/pci-stub.c
+++ b/hw/pci/pci-stub.c
@@ -40,8 +40,7 @@ void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
-    monitor_printf(mon, "PCI devices not supported\n");
+    monitor_hmp_printf(hmp, "PCI devices not supported\n");
 }
 
 /* kvm-all wants this */
diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
index d8afaf730639..b5e56a16cce1 100644
--- a/hw/s390x/s390-skeys.c
+++ b/hw/s390x/s390-skeys.c
@@ -106,7 +106,6 @@ static void write_keys(FILE *f, uint8_t *keys, uint64_t startgfn,
 
 void hmp_info_skeys(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     S390SKeysState *ss = s390_get_skeys_device();
     S390SKeysClass *skeyclass = S390_SKEYS_GET_CLASS(ss);
     uint64_t addr = qdict_get_int(qdict, "addr");
@@ -115,24 +114,24 @@ void hmp_info_skeys(MonitorHMP *hmp, const QDict *qdict)
 
     /* Quick check to see if guest is using storage keys*/
     if (!skeyclass->skeys_are_enabled(ss)) {
-        monitor_printf(mon, "Error: This guest is not using storage keys\n");
+        monitor_hmp_printf(hmp, "Error: This guest is not using storage keys\n");
         return;
     }
 
     if (!address_space_access_valid(&address_space_memory,
                                     addr & TARGET_PAGE_MASK, TARGET_PAGE_SIZE,
                                     false, MEMTXATTRS_UNSPECIFIED)) {
-        monitor_printf(mon, "Error: The given address is not valid\n");
+        monitor_hmp_printf(hmp, "Error: The given address is not valid\n");
         return;
     }
 
     r = skeyclass->get_skeys(ss, addr / TARGET_PAGE_SIZE, 1, &key);
     if (r < 0) {
-        monitor_printf(mon, "Error: %s\n", strerror(-r));
+        monitor_hmp_printf(hmp, "Error: %s\n", strerror(-r));
         return;
     }
 
-    monitor_printf(mon, "  key: 0x%X\n", key);
+    monitor_hmp_printf(hmp, "  key: 0x%X\n", key);
 }
 
 void hmp_dump_skeys(MonitorHMP *hmp, const QDict *qdict)
diff --git a/hw/s390x/s390-stattrib.c b/hw/s390x/s390-stattrib.c
index b4a405455901..644298f7f0b2 100644
--- a/hw/s390x/s390-stattrib.c
+++ b/hw/s390x/s390-stattrib.c
@@ -61,7 +61,6 @@ void s390_stattrib_init(void)
 
 void hmp_migrationmode(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     S390StAttribState *sas = s390_get_stattrib_device();
     S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
     uint64_t what = qdict_get_int(qdict, "mode");
@@ -70,14 +69,13 @@ void hmp_migrationmode(MonitorHMP *hmp, const QDict *qdict)
 
     r = sac->set_migrationmode(sas, what, &local_err);
     if (r < 0) {
-        monitor_printf(mon, "Error: %s", error_get_pretty(local_err));
+        monitor_hmp_printf(hmp, "Error: %s", error_get_pretty(local_err));
         error_free(local_err);
     }
 }
 
 void hmp_info_cmma(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     S390StAttribState *sas = s390_get_stattrib_device();
     S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
     uint64_t addr = qdict_get_int(qdict, "addr");
@@ -87,27 +85,27 @@ void hmp_info_cmma(MonitorHMP *hmp, const QDict *qdict)
 
     vals = g_try_malloc(buflen);
     if (!vals) {
-        monitor_printf(mon, "Error: %s\n", strerror(errno));
+        monitor_hmp_printf(hmp, "Error: %s\n", strerror(errno));
         return;
     }
 
     len = sac->peek_stattr(sas, addr / TARGET_PAGE_SIZE, buflen, vals);
     if (len < 0) {
-        monitor_printf(mon, "Error: %s", strerror(-len));
+        monitor_hmp_printf(hmp, "Error: %s", strerror(-len));
         goto out;
     }
 
-    monitor_printf(mon, "  CMMA attributes, "
-                   "pages %" PRIu64 "+%d (0x%" PRIx64 "):\n",
-                   addr / TARGET_PAGE_SIZE, len, addr & ~TARGET_PAGE_MASK);
+    monitor_hmp_printf(hmp, "  CMMA attributes, "
+                       "pages %" PRIu64 "+%d (0x%" PRIx64 "):\n",
+                       addr / TARGET_PAGE_SIZE, len, addr & ~TARGET_PAGE_MASK);
     for (cx = 0; cx < len; cx++) {
         if (cx % 8 == 7) {
-            monitor_printf(mon, "%02x\n", vals[cx]);
+            monitor_hmp_printf(hmp, "%02x\n", vals[cx]);
         } else {
-            monitor_printf(mon, "%02x", vals[cx]);
+            monitor_hmp_printf(hmp, "%02x", vals[cx]);
         }
     }
-    monitor_printf(mon, "\n");
+    monitor_hmp_printf(hmp, "\n");
 
 out:
     g_free(vals);
diff --git a/hw/uefi/ovmf-log.c b/hw/uefi/ovmf-log.c
index 0d59a74ad60e..0249eea2cfe9 100644
--- a/hw/uefi/ovmf-log.c
+++ b/hw/uefi/ovmf-log.c
@@ -258,7 +258,6 @@ FirmwareLog *qmp_query_firmware_log(bool have_max_size, uint64_t max_size,
 
 void hmp_info_firmware_log(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     g_autofree gchar *log_esc = NULL;
     g_autofree guchar *log_out = NULL;
     Error *err = NULL;
@@ -278,10 +277,10 @@ void hmp_info_firmware_log(MonitorHMP *hmp, const QDict *qdict)
 
     if (log->version) {
         g_autofree gchar *esc = g_strescape(log->version, NULL);
-        monitor_printf(mon, "[ firmware version: %s ]\n", esc);
+        monitor_hmp_printf(hmp, "[ firmware version: %s ]\n", esc);
     }
 
     log_out = g_base64_decode(log->log, &log_len);
     log_esc = g_strescape((gchar *)log_out, "\r\n");
-    monitor_printf(mon, "%s\n", log_esc);
+    monitor_hmp_printf(hmp, "%s\n", log_esc);
 }
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 9b9b2e7c2f8f..fe3dbfa2227c 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -546,14 +546,15 @@ static const char *usb_speed(unsigned int speed)
 
 static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
 {
+    MonitorHMP *hmp = MONITOR_HMP(mon);
     USBDevice *dev = USB_DEVICE(qdev);
     USBBus *bus = usb_bus_from_device(dev);
 
-    monitor_printf(mon, "%*saddr %d.%d, port %s, speed %s, name %s%s\n",
-                   indent, "", bus->busnr, dev->addr,
-                   dev->port ? dev->port->path : "-",
-                   usb_speed(dev->speed), dev->product_desc,
-                   dev->attached ? ", attached" : "");
+    monitor_hmp_printf(hmp, "%*saddr %d.%d, port %s, speed %s, name %s%s\n",
+                       indent, "", bus->busnr, dev->addr,
+                       dev->port ? dev->port->path : "-",
+                       usb_speed(dev->speed), dev->product_desc,
+                       dev->attached ? ", attached" : "");
 }
 
 static char *usb_get_dev_path(DeviceState *qdev)
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index c02343d3a655..9b9f26a1078e 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1922,7 +1922,6 @@ static void usb_host_auto_check(void *unused)
 
 void hmp_info_usbhost(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     libusb_device **devs = NULL;
     struct libusb_device_descriptor ddesc;
     char port[16];
@@ -1941,14 +1940,14 @@ void hmp_info_usbhost(MonitorHMP *hmp, const QDict *qdict)
             continue;
         }
         usb_host_get_port(devs[i], port, sizeof(port));
-        monitor_printf(mon, "  Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
-                       libusb_get_bus_number(devs[i]),
-                       libusb_get_device_address(devs[i]),
-                       port,
-                       speed_name[libusb_get_device_speed(devs[i])]);
-        monitor_printf(mon, "    Class %02x:", ddesc.bDeviceClass);
-        monitor_printf(mon, " USB device %04x:%04x",
-                       ddesc.idVendor, ddesc.idProduct);
+        monitor_hmp_printf(hmp, "  Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
+                           libusb_get_bus_number(devs[i]),
+                           libusb_get_device_address(devs[i]),
+                           port,
+                           speed_name[libusb_get_device_speed(devs[i])]);
+        monitor_hmp_printf(hmp, "    Class %02x:", ddesc.bDeviceClass);
+        monitor_hmp_printf(hmp, " USB device %04x:%04x",
+                           ddesc.idVendor, ddesc.idProduct);
         if (ddesc.iProduct) {
             libusb_device_handle *handle;
             if (libusb_open(devs[i], &handle) == 0) {
@@ -1957,10 +1956,10 @@ void hmp_info_usbhost(MonitorHMP *hmp, const QDict *qdict)
                                                    ddesc.iProduct,
                                                    name, sizeof(name));
                 libusb_close(handle);
-                monitor_printf(mon, ", %s", name);
+                monitor_hmp_printf(hmp, ", %s", name);
             }
         }
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "\n");
     }
     libusb_free_device_list(devs, 1);
 }
diff --git a/hw/virtio/virtio-hmp-cmds.c b/hw/virtio/virtio-hmp-cmds.c
index fb36c8b9274c..e5da6f00699d 100644
--- a/hw/virtio/virtio-hmp-cmds.c
+++ b/hw/virtio/virtio-hmp-cmds.c
@@ -12,77 +12,76 @@
 #include "qobject/qdict.h"
 
 
-static void hmp_virtio_dump_protocols(Monitor *mon,
+static void hmp_virtio_dump_protocols(MonitorHMP *hmp,
                                       VhostDeviceProtocols *pcol)
 {
     strList *pcol_list = pcol->protocols;
     while (pcol_list) {
-        monitor_printf(mon, "\t%s", pcol_list->value);
+        monitor_hmp_printf(hmp, "\t%s", pcol_list->value);
         pcol_list = pcol_list->next;
         if (pcol_list != NULL) {
-            monitor_printf(mon, ",\n");
+            monitor_hmp_printf(hmp, ",\n");
         }
     }
-    monitor_printf(mon, "\n");
+    monitor_hmp_printf(hmp, "\n");
     if (pcol->has_unknown_protocols) {
-        monitor_printf(mon, "  unknown-protocols(0x%016"PRIx64")\n",
-                       pcol->unknown_protocols);
+        monitor_hmp_printf(hmp, "  unknown-protocols(0x%016"PRIx64")\n",
+                           pcol->unknown_protocols);
     }
 }
 
-static void hmp_virtio_dump_status(Monitor *mon,
+static void hmp_virtio_dump_status(MonitorHMP *hmp,
                                    VirtioDeviceStatus *status)
 {
     strList *status_list = status->statuses;
     while (status_list) {
-        monitor_printf(mon, "\t%s", status_list->value);
+        monitor_hmp_printf(hmp, "\t%s", status_list->value);
         status_list = status_list->next;
         if (status_list != NULL) {
-            monitor_printf(mon, ",\n");
+            monitor_hmp_printf(hmp, ",\n");
         }
     }
-    monitor_printf(mon, "\n");
+    monitor_hmp_printf(hmp, "\n");
     if (status->has_unknown_statuses) {
-        monitor_printf(mon, "  unknown-statuses(0x%016"PRIx32")\n",
-                       status->unknown_statuses);
+        monitor_hmp_printf(hmp, "  unknown-statuses(0x%016"PRIx32")\n",
+                           status->unknown_statuses);
     }
 }
 
-static void hmp_virtio_dump_features(Monitor *mon,
+static void hmp_virtio_dump_features(MonitorHMP *hmp,
                                      VirtioDeviceFeatures *features)
 {
     strList *transport_list = features->transports;
     while (transport_list) {
-        monitor_printf(mon, "\t%s", transport_list->value);
+        monitor_hmp_printf(hmp, "\t%s", transport_list->value);
         transport_list = transport_list->next;
         if (transport_list != NULL) {
-            monitor_printf(mon, ",\n");
+            monitor_hmp_printf(hmp, ",\n");
         }
     }
 
-    monitor_printf(mon, "\n");
+    monitor_hmp_printf(hmp, "\n");
     strList *list = features->dev_features;
     if (list) {
         while (list) {
-            monitor_printf(mon, "\t%s", list->value);
+            monitor_hmp_printf(hmp, "\t%s", list->value);
             list = list->next;
             if (list != NULL) {
-                monitor_printf(mon, ",\n");
+                monitor_hmp_printf(hmp, ",\n");
             }
         }
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "\n");
     }
 
     if (features->has_unknown_dev_features) {
-        monitor_printf(mon, "  unknown-features(0x%016"PRIx64"%016"PRIx64")\n",
-                       features->unknown_dev_features2,
-                       features->unknown_dev_features);
+        monitor_hmp_printf(hmp, "  unknown-features(0x%016"PRIx64"%016"PRIx64")\n",
+                           features->unknown_dev_features2,
+                           features->unknown_dev_features);
     }
 }
 
 void hmp_virtio_query(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     VirtioInfoList *list = qmp_x_query_virtio(&err);
     VirtioInfoList *node;
@@ -93,14 +92,14 @@ void hmp_virtio_query(MonitorHMP *hmp, const QDict *qdict)
     }
 
     if (list == NULL) {
-        monitor_printf(mon, "No VirtIO devices\n");
+        monitor_hmp_printf(hmp, "No VirtIO devices\n");
         return;
     }
 
     node = list;
     while (node) {
-        monitor_printf(mon, "%s [%s]\n", node->value->path,
-                       node->value->name);
+        monitor_hmp_printf(hmp, "%s [%s]\n", node->value->path,
+                           node->value->name);
         node = node->next;
     }
     qapi_free_VirtioInfoList(list);
@@ -108,7 +107,6 @@ void hmp_virtio_query(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_virtio_status(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *path = qdict_get_try_str(qdict, "path");
     VirtioStatus *s = qmp_x_query_virtio_status(path, &err);
@@ -118,68 +116,68 @@ void hmp_virtio_status(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "%s:\n", path);
-    monitor_printf(mon, "  device_name:             %s %s\n",
-                   s->name, s->vhost_dev ? "(vhost)" : "");
-    monitor_printf(mon, "  device_id:               %d\n", s->device_id);
-    monitor_printf(mon, "  vhost_started:           %s\n",
-                   s->vhost_started ? "true" : "false");
-    monitor_printf(mon, "  bus_name:                %s\n", s->bus_name);
-    monitor_printf(mon, "  broken:                  %s\n",
-                   s->broken ? "true" : "false");
-    monitor_printf(mon, "  disabled:                %s\n",
-                   s->disabled ? "true" : "false");
-    monitor_printf(mon, "  disable_legacy_check:    %s\n",
-                   s->disable_legacy_check ? "true" : "false");
-    monitor_printf(mon, "  started:                 %s\n",
-                   s->started ? "true" : "false");
-    monitor_printf(mon, "  use_started:             %s\n",
-                   s->use_started ? "true" : "false");
-    monitor_printf(mon, "  start_on_kick:           %s\n",
-                   s->start_on_kick ? "true" : "false");
-    monitor_printf(mon, "  use_guest_notifier_mask: %s\n",
-                   s->use_guest_notifier_mask ? "true" : "false");
-    monitor_printf(mon, "  vm_running:              %s\n",
-                   s->vm_running ? "true" : "false");
-    monitor_printf(mon, "  num_vqs:                 %"PRId64"\n", s->num_vqs);
-    monitor_printf(mon, "  queue_sel:               %d\n",
-                   s->queue_sel);
-    monitor_printf(mon, "  isr:                     %d\n", s->isr);
-    monitor_printf(mon, "  endianness:              %s\n",
-                   s->device_endian);
-    monitor_printf(mon, "  status:\n");
-    hmp_virtio_dump_status(mon, s->status);
-    monitor_printf(mon, "  Guest features:\n");
-    hmp_virtio_dump_features(mon, s->guest_features);
-    monitor_printf(mon, "  Host features:\n");
-    hmp_virtio_dump_features(mon, s->host_features);
-    monitor_printf(mon, "  Backend features:\n");
-    hmp_virtio_dump_features(mon, s->backend_features);
+    monitor_hmp_printf(hmp, "%s:\n", path);
+    monitor_hmp_printf(hmp, "  device_name:             %s %s\n",
+                       s->name, s->vhost_dev ? "(vhost)" : "");
+    monitor_hmp_printf(hmp, "  device_id:               %d\n", s->device_id);
+    monitor_hmp_printf(hmp, "  vhost_started:           %s\n",
+                       s->vhost_started ? "true" : "false");
+    monitor_hmp_printf(hmp, "  bus_name:                %s\n", s->bus_name);
+    monitor_hmp_printf(hmp, "  broken:                  %s\n",
+                       s->broken ? "true" : "false");
+    monitor_hmp_printf(hmp, "  disabled:                %s\n",
+                       s->disabled ? "true" : "false");
+    monitor_hmp_printf(hmp, "  disable_legacy_check:    %s\n",
+                       s->disable_legacy_check ? "true" : "false");
+    monitor_hmp_printf(hmp, "  started:                 %s\n",
+                       s->started ? "true" : "false");
+    monitor_hmp_printf(hmp, "  use_started:             %s\n",
+                       s->use_started ? "true" : "false");
+    monitor_hmp_printf(hmp, "  start_on_kick:           %s\n",
+                       s->start_on_kick ? "true" : "false");
+    monitor_hmp_printf(hmp, "  use_guest_notifier_mask: %s\n",
+                       s->use_guest_notifier_mask ? "true" : "false");
+    monitor_hmp_printf(hmp, "  vm_running:              %s\n",
+                       s->vm_running ? "true" : "false");
+    monitor_hmp_printf(hmp, "  num_vqs:                 %"PRId64"\n", s->num_vqs);
+    monitor_hmp_printf(hmp, "  queue_sel:               %d\n",
+                       s->queue_sel);
+    monitor_hmp_printf(hmp, "  isr:                     %d\n", s->isr);
+    monitor_hmp_printf(hmp, "  endianness:              %s\n",
+                       s->device_endian);
+    monitor_hmp_printf(hmp, "  status:\n");
+    hmp_virtio_dump_status(hmp, s->status);
+    monitor_hmp_printf(hmp, "  Guest features:\n");
+    hmp_virtio_dump_features(hmp, s->guest_features);
+    monitor_hmp_printf(hmp, "  Host features:\n");
+    hmp_virtio_dump_features(hmp, s->host_features);
+    monitor_hmp_printf(hmp, "  Backend features:\n");
+    hmp_virtio_dump_features(hmp, s->backend_features);
 
     if (s->vhost_dev) {
-        monitor_printf(mon, "  VHost:\n");
-        monitor_printf(mon, "    nvqs:           %d\n",
-                       s->vhost_dev->nvqs);
-        monitor_printf(mon, "    vq_index:       %"PRId64"\n",
-                       s->vhost_dev->vq_index);
-        monitor_printf(mon, "    max_queues:     %"PRId64"\n",
-                       s->vhost_dev->max_queues);
-        monitor_printf(mon, "    n_mem_sections: %"PRId64"\n",
-                       s->vhost_dev->n_mem_sections);
-        monitor_printf(mon, "    n_tmp_sections: %"PRId64"\n",
-                       s->vhost_dev->n_tmp_sections);
-        monitor_printf(mon, "    backend_cap:    %"PRId64"\n",
-                       s->vhost_dev->backend_cap);
-        monitor_printf(mon, "    log_enabled:    %s\n",
-                       s->vhost_dev->log_enabled ? "true" : "false");
-        monitor_printf(mon, "    log_size:       %"PRId64"\n",
-                       s->vhost_dev->log_size);
-        monitor_printf(mon, "    Features:\n");
-        hmp_virtio_dump_features(mon, s->vhost_dev->features);
-        monitor_printf(mon, "    Acked features:\n");
-        hmp_virtio_dump_features(mon, s->vhost_dev->acked_features);
-        monitor_printf(mon, "    Protocol features:\n");
-        hmp_virtio_dump_protocols(mon, s->vhost_dev->protocol_features);
+        monitor_hmp_printf(hmp, "  VHost:\n");
+        monitor_hmp_printf(hmp, "    nvqs:           %d\n",
+                           s->vhost_dev->nvqs);
+        monitor_hmp_printf(hmp, "    vq_index:       %"PRId64"\n",
+                           s->vhost_dev->vq_index);
+        monitor_hmp_printf(hmp, "    max_queues:     %"PRId64"\n",
+                           s->vhost_dev->max_queues);
+        monitor_hmp_printf(hmp, "    n_mem_sections: %"PRId64"\n",
+                           s->vhost_dev->n_mem_sections);
+        monitor_hmp_printf(hmp, "    n_tmp_sections: %"PRId64"\n",
+                           s->vhost_dev->n_tmp_sections);
+        monitor_hmp_printf(hmp, "    backend_cap:    %"PRId64"\n",
+                           s->vhost_dev->backend_cap);
+        monitor_hmp_printf(hmp, "    log_enabled:    %s\n",
+                           s->vhost_dev->log_enabled ? "true" : "false");
+        monitor_hmp_printf(hmp, "    log_size:       %"PRId64"\n",
+                           s->vhost_dev->log_size);
+        monitor_hmp_printf(hmp, "    Features:\n");
+        hmp_virtio_dump_features(hmp, s->vhost_dev->features);
+        monitor_hmp_printf(hmp, "    Acked features:\n");
+        hmp_virtio_dump_features(hmp, s->vhost_dev->acked_features);
+        monitor_hmp_printf(hmp, "    Protocol features:\n");
+        hmp_virtio_dump_protocols(hmp, s->vhost_dev->protocol_features);
     }
 
     qapi_free_VirtioStatus(s);
@@ -187,7 +185,6 @@ void hmp_virtio_status(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_vhost_queue_status(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *path = qdict_get_try_str(qdict, "path");
     int queue = qdict_get_int(qdict, "queue");
@@ -199,29 +196,28 @@ void hmp_vhost_queue_status(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "%s:\n", path);
-    monitor_printf(mon, "  device_name:          %s (vhost)\n",
-                   s->name);
-    monitor_printf(mon, "  kick:                 %"PRId64"\n", s->kick);
-    monitor_printf(mon, "  call:                 %"PRId64"\n", s->call);
-    monitor_printf(mon, "  VRing:\n");
-    monitor_printf(mon, "    num:         %"PRId64"\n", s->num);
-    monitor_printf(mon, "    desc_phys:   0x%016"PRIx64"\n",
-                   s->desc_phys);
-    monitor_printf(mon, "    desc_size:   %"PRId32"\n", s->desc_size);
-    monitor_printf(mon, "    avail_phys:  0x%016"PRIx64"\n",
-                   s->avail_phys);
-    monitor_printf(mon, "    avail_size:  %"PRId32"\n", s->avail_size);
-    monitor_printf(mon, "    used_phys:   0x%016"PRIx64"\n",
-                   s->used_phys);
-    monitor_printf(mon, "    used_size:   %"PRId32"\n", s->used_size);
+    monitor_hmp_printf(hmp, "%s:\n", path);
+    monitor_hmp_printf(hmp, "  device_name:          %s (vhost)\n",
+                       s->name);
+    monitor_hmp_printf(hmp, "  kick:                 %"PRId64"\n", s->kick);
+    monitor_hmp_printf(hmp, "  call:                 %"PRId64"\n", s->call);
+    monitor_hmp_printf(hmp, "  VRing:\n");
+    monitor_hmp_printf(hmp, "    num:         %"PRId64"\n", s->num);
+    monitor_hmp_printf(hmp, "    desc_phys:   0x%016"PRIx64"\n",
+                       s->desc_phys);
+    monitor_hmp_printf(hmp, "    desc_size:   %"PRId32"\n", s->desc_size);
+    monitor_hmp_printf(hmp, "    avail_phys:  0x%016"PRIx64"\n",
+                       s->avail_phys);
+    monitor_hmp_printf(hmp, "    avail_size:  %"PRId32"\n", s->avail_size);
+    monitor_hmp_printf(hmp, "    used_phys:   0x%016"PRIx64"\n",
+                       s->used_phys);
+    monitor_hmp_printf(hmp, "    used_size:   %"PRId32"\n", s->used_size);
 
     qapi_free_VirtVhostQueueStatus(s);
 }
 
 void hmp_virtio_queue_status(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *path = qdict_get_try_str(qdict, "path");
     int queue = qdict_get_int(qdict, "queue");
@@ -232,42 +228,41 @@ void hmp_virtio_queue_status(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "%s:\n", path);
-    monitor_printf(mon, "  device_name:          %s\n", s->name);
-    monitor_printf(mon, "  queue_index:          %d\n", s->queue_index);
-    monitor_printf(mon, "  inuse:                %d\n", s->inuse);
-    monitor_printf(mon, "  used_idx:             %d\n", s->used_idx);
-    monitor_printf(mon, "  signalled_used:       %d\n",
-                   s->signalled_used);
-    monitor_printf(mon, "  signalled_used_valid: %s\n",
-                   s->signalled_used_valid ? "true" : "false");
+    monitor_hmp_printf(hmp, "%s:\n", path);
+    monitor_hmp_printf(hmp, "  device_name:          %s\n", s->name);
+    monitor_hmp_printf(hmp, "  queue_index:          %d\n", s->queue_index);
+    monitor_hmp_printf(hmp, "  inuse:                %d\n", s->inuse);
+    monitor_hmp_printf(hmp, "  used_idx:             %d\n", s->used_idx);
+    monitor_hmp_printf(hmp, "  signalled_used:       %d\n",
+                       s->signalled_used);
+    monitor_hmp_printf(hmp, "  signalled_used_valid: %s\n",
+                       s->signalled_used_valid ? "true" : "false");
     if (s->has_last_avail_idx) {
-        monitor_printf(mon, "  last_avail_idx:       %d\n",
-                       s->last_avail_idx);
+        monitor_hmp_printf(hmp, "  last_avail_idx:       %d\n",
+                           s->last_avail_idx);
     }
     if (s->has_shadow_avail_idx) {
-        monitor_printf(mon, "  shadow_avail_idx:     %d\n",
-                       s->shadow_avail_idx);
+        monitor_hmp_printf(hmp, "  shadow_avail_idx:     %d\n",
+                           s->shadow_avail_idx);
     }
-    monitor_printf(mon, "  VRing:\n");
-    monitor_printf(mon, "    num:          %"PRId32"\n", s->vring_num);
-    monitor_printf(mon, "    num_default:  %"PRId32"\n",
-                   s->vring_num_default);
-    monitor_printf(mon, "    align:        %"PRId32"\n",
-                   s->vring_align);
-    monitor_printf(mon, "    desc:         0x%016"PRIx64"\n",
-                   s->vring_desc);
-    monitor_printf(mon, "    avail:        0x%016"PRIx64"\n",
-                   s->vring_avail);
-    monitor_printf(mon, "    used:         0x%016"PRIx64"\n",
-                   s->vring_used);
+    monitor_hmp_printf(hmp, "  VRing:\n");
+    monitor_hmp_printf(hmp, "    num:          %"PRId32"\n", s->vring_num);
+    monitor_hmp_printf(hmp, "    num_default:  %"PRId32"\n",
+                       s->vring_num_default);
+    monitor_hmp_printf(hmp, "    align:        %"PRId32"\n",
+                       s->vring_align);
+    monitor_hmp_printf(hmp, "    desc:         0x%016"PRIx64"\n",
+                       s->vring_desc);
+    monitor_hmp_printf(hmp, "    avail:        0x%016"PRIx64"\n",
+                       s->vring_avail);
+    monitor_hmp_printf(hmp, "    used:         0x%016"PRIx64"\n",
+                       s->vring_used);
 
     qapi_free_VirtQueueStatus(s);
 }
 
 void hmp_virtio_queue_element(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *path = qdict_get_try_str(qdict, "path");
     int queue = qdict_get_int(qdict, "queue");
@@ -282,41 +277,41 @@ void hmp_virtio_queue_element(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "%s:\n", path);
-    monitor_printf(mon, "  device_name: %s\n", e->name);
-    monitor_printf(mon, "  index:   %d\n", e->index);
-    monitor_printf(mon, "  desc:\n");
-    monitor_printf(mon, "    descs:\n");
+    monitor_hmp_printf(hmp, "%s:\n", path);
+    monitor_hmp_printf(hmp, "  device_name: %s\n", e->name);
+    monitor_hmp_printf(hmp, "  index:   %d\n", e->index);
+    monitor_hmp_printf(hmp, "  desc:\n");
+    monitor_hmp_printf(hmp, "    descs:\n");
 
     list = e->descs;
     while (list) {
-        monitor_printf(mon, "        addr 0x%"PRIx64" len %d",
-                       list->value->addr, list->value->len);
+        monitor_hmp_printf(hmp, "        addr 0x%"PRIx64" len %d",
+                           list->value->addr, list->value->len);
         if (list->value->flags) {
             strList *flag = list->value->flags;
-            monitor_printf(mon, " (");
+            monitor_hmp_printf(hmp, " (");
             while (flag) {
-                monitor_printf(mon, "%s", flag->value);
+                monitor_hmp_printf(hmp, "%s", flag->value);
                 flag = flag->next;
                 if (flag) {
-                    monitor_printf(mon, ", ");
+                    monitor_hmp_printf(hmp, ", ");
                 }
             }
-            monitor_printf(mon, ")");
+            monitor_hmp_printf(hmp, ")");
         }
         list = list->next;
         if (list) {
-            monitor_printf(mon, ",\n");
+            monitor_hmp_printf(hmp, ",\n");
         }
     }
-    monitor_printf(mon, "\n");
-    monitor_printf(mon, "  avail:\n");
-    monitor_printf(mon, "    flags: %d\n", e->avail->flags);
-    monitor_printf(mon, "    idx:   %d\n", e->avail->idx);
-    monitor_printf(mon, "    ring:  %d\n", e->avail->ring);
-    monitor_printf(mon, "  used:\n");
-    monitor_printf(mon, "    flags: %d\n", e->used->flags);
-    monitor_printf(mon, "    idx:   %d\n", e->used->idx);
+    monitor_hmp_printf(hmp, "\n");
+    monitor_hmp_printf(hmp, "  avail:\n");
+    monitor_hmp_printf(hmp, "    flags: %d\n", e->avail->flags);
+    monitor_hmp_printf(hmp, "    idx:   %d\n", e->avail->idx);
+    monitor_hmp_printf(hmp, "    ring:  %d\n", e->avail->ring);
+    monitor_hmp_printf(hmp, "  used:\n");
+    monitor_hmp_printf(hmp, "    flags: %d\n", e->used->flags);
+    monitor_hmp_printf(hmp, "    idx:   %d\n", e->used->idx);
 
     qapi_free_VirtioQueueElement(e);
 }
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index a563f6066bb4..4075b5b001ae 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -103,10 +103,11 @@ abort:
 
 static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
 {
+    MonitorHMP *hmp = MONITOR_HMP(mon);
     XenDevice *xendev = XEN_DEVICE(dev);
 
-    monitor_printf(mon, "%*sname = '%s' frontend_id = %u\n",
-                   indent, "", xendev->name, xendev->frontend_id);
+    monitor_hmp_printf(hmp, "%*sname = '%s' frontend_id = %u\n",
+                       indent, "", xendev->name, xendev->frontend_id);
 }
 
 static char *xen_bus_get_dev_path(DeviceState *dev)
diff --git a/include/disas/disas.h b/include/disas/disas.h
index c702b1effc1c..47daa9b4d2df 100644
--- a/include/disas/disas.h
+++ b/include/disas/disas.h
@@ -1,13 +1,15 @@
 #ifndef QEMU_DISAS_H
 #define QEMU_DISAS_H
 
+#include "monitor/hmp.h"
+
 /* Disassemble this for me please... (debugging). */
 #ifdef CONFIG_TCG
 void disas(FILE *out, const void *code, size_t size);
 void target_disas(FILE *out, CPUState *cpu, const DisasContextBase *db);
 #endif
 
-void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc,
+void monitor_disas(MonitorHMP *hmp, CPUState *cpu, uint64_t pc,
                    int nb_insn, bool is_physical);
 
 #ifdef CONFIG_PLUGIN
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index 3fd17048b319..f10bf83df86d 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -38,10 +38,10 @@ void monitor_new_hmp(const char *id, const char *chardev_id,
 
 MonitorHMP *monitor_cur_hmp(void);
 
-int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
+int monitor_hmp_vprintf(MonitorHMP *mon, const char *fmt, va_list ap)
     G_GNUC_PRINTF(2, 0);
-int monitor_printf(Monitor *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
-void monitor_printc(Monitor *mon, int ch);
+int monitor_hmp_printf(MonitorHMP *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
+void monitor_hmp_printc(MonitorHMP *mon, int ch);
 
 void monitor_hmp_read_command(MonitorHMP *hmp, int show_prompt);
 int monitor_hmp_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
@@ -58,7 +58,7 @@ CPUState *monitor_hmp_get_cpu(MonitorHMP *hmp);
 int monitor_hmp_get_cpu_index(MonitorHMP *hmp);
 
 bool hmp_handle_error(MonitorHMP *hmp, Error *err);
-void hmp_help_cmd(Monitor *mon, const char *name);
+void hmp_help_cmd(MonitorHMP *hmp, const char *name);
 strList *hmp_split_at_comma(const char *str);
 
 void hmp_info_name(MonitorHMP *hmp, const QDict *qdict);
@@ -114,11 +114,11 @@ void hmp_set_password(MonitorHMP *hmp, const QDict *qdict);
 void hmp_expire_password(MonitorHMP *hmp, const QDict *qdict);
 void hmp_change(MonitorHMP *hmp, const QDict *qdict);
 #ifdef CONFIG_VNC
-void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
+void hmp_change_vnc(MonitorHMP *hmp, const char *device, const char *target,
                     const char *arg, const char *read_only, bool force,
                     Error **errp);
 #endif
-void hmp_change_medium(Monitor *mon, const char *device, const char *target,
+void hmp_change_medium(MonitorHMP *hmp, const char *device, const char *target,
                        const char *arg, const char *read_only, bool force,
                        Error **errp);
 void hmp_migrate(MonitorHMP *hmp, const QDict *qdict);
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index 3c0931796ce2..bdbb2aaa99db 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -858,34 +858,33 @@ struct DirtyRateInfo *qmp_query_dirty_rate(bool has_calc_time_unit,
 
 void hmp_info_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     DirtyRateInfo *info = query_dirty_rate_info(TIME_UNIT_SECOND);
 
-    monitor_printf(mon, "Status: %s\n",
-                   DirtyRateStatus_str(info->status));
-    monitor_printf(mon, "Start Time: %"PRIi64" (ms)\n",
-                   info->start_time);
+    monitor_hmp_printf(hmp, "Status: %s\n",
+                       DirtyRateStatus_str(info->status));
+    monitor_hmp_printf(hmp, "Start Time: %"PRIi64" (ms)\n",
+                       info->start_time);
     if (info->mode == DIRTY_RATE_MEASURE_MODE_PAGE_SAMPLING) {
-        monitor_printf(mon, "Sample Pages: %"PRIu64" (per GB)\n",
-                       info->sample_pages);
+        monitor_hmp_printf(hmp, "Sample Pages: %"PRIu64" (per GB)\n",
+                           info->sample_pages);
     }
-    monitor_printf(mon, "Period: %"PRIi64" (sec)\n",
-                   info->calc_time);
-    monitor_printf(mon, "Mode: %s\n",
-                   DirtyRateMeasureMode_str(info->mode));
-    monitor_printf(mon, "Dirty rate: ");
+    monitor_hmp_printf(hmp, "Period: %"PRIi64" (sec)\n",
+                       info->calc_time);
+    monitor_hmp_printf(hmp, "Mode: %s\n",
+                       DirtyRateMeasureMode_str(info->mode));
+    monitor_hmp_printf(hmp, "Dirty rate: ");
     if (info->has_dirty_rate) {
-        monitor_printf(mon, "%"PRIi64" (MB/s)\n", info->dirty_rate);
+        monitor_hmp_printf(hmp, "%"PRIi64" (MB/s)\n", info->dirty_rate);
         if (info->has_vcpu_dirty_rate) {
             DirtyRateVcpuList *rate, *head = info->vcpu_dirty_rate;
             for (rate = head; rate != NULL; rate = rate->next) {
-                monitor_printf(mon, "vcpu[%"PRIi64"], Dirty rate: %"PRIi64
-                               " (MB/s)\n", rate->value->id,
-                               rate->value->dirty_rate);
+                monitor_hmp_printf(hmp, "vcpu[%"PRIi64"], Dirty rate: %"PRIi64
+                                   " (MB/s)\n", rate->value->id,
+                                   rate->value->dirty_rate);
             }
         }
     } else {
-        monitor_printf(mon, "(not ready)\n");
+        monitor_hmp_printf(hmp, "(not ready)\n");
     }
 
     qapi_free_DirtyRateVcpuList(info->vcpu_dirty_rate);
@@ -894,7 +893,6 @@ void hmp_info_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_calc_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int64_t sec = qdict_get_try_int(qdict, "second", 0);
     int64_t sample_pages = qdict_get_try_int(qdict, "sample_pages_per_GB", -1);
     bool has_sample_pages = (sample_pages != -1);
@@ -904,13 +902,13 @@ void hmp_calc_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
     Error *err = NULL;
 
     if (!sec) {
-        monitor_printf(mon, "Incorrect period length specified!\n");
+        monitor_hmp_printf(hmp, "Incorrect period length specified!\n");
         return;
     }
 
     if (dirty_ring && dirty_bitmap) {
-        monitor_printf(mon, "Either dirty ring or dirty bitmap "
-                       "can be specified!\n");
+        monitor_hmp_printf(hmp, "Either dirty ring or dirty bitmap "
+                           "can be specified!\n");
         return;
     }
 
@@ -930,7 +928,7 @@ void hmp_calc_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "Starting dirty rate measurement with period %"PRIi64
-                   " seconds\n", sec);
-    monitor_printf(mon, "[Please use 'info dirty_rate' to check results]\n");
+    monitor_hmp_printf(hmp, "Starting dirty rate measurement with period %"PRIi64
+                       " seconds\n", sec);
+    monitor_hmp_printf(hmp, "[Please use 'info dirty_rate' to check results]\n");
 }
diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c
index 73a974259478..6fe189471899 100644
--- a/migration/migration-hmp-cmds.c
+++ b/migration/migration-hmp-cmds.c
@@ -36,23 +36,23 @@
 #include "options.h"
 #include "migration.h"
 
-static void migration_global_dump(Monitor *mon)
+static void migration_global_dump(MonitorHMP *hmp)
 {
     MigrationState *ms = migrate_get_current();
 
-    monitor_printf(mon, "Globals:\n");
-    monitor_printf(mon, "  store-global-state: %s\n",
-                   ms->store_global_state ? "on" : "off");
-    monitor_printf(mon, "  only-migratable: %s\n",
-                   only_migratable ? "on" : "off");
-    monitor_printf(mon, "  send-configuration: %s\n",
-                   ms->send_configuration ? "on" : "off");
-    monitor_printf(mon, "  send-section-footer: %s\n",
-                   ms->send_section_footer ? "on" : "off");
-    monitor_printf(mon, "  send-switchover-start: %s\n",
-                   ms->send_switchover_start ? "on" : "off");
-    monitor_printf(mon, "  clear-bitmap-shift: %u\n",
-                   ms->clear_bitmap_shift);
+    monitor_hmp_printf(hmp, "Globals:\n");
+    monitor_hmp_printf(hmp, "  store-global-state: %s\n",
+                       ms->store_global_state ? "on" : "off");
+    monitor_hmp_printf(hmp, "  only-migratable: %s\n",
+                       only_migratable ? "on" : "off");
+    monitor_hmp_printf(hmp, "  send-configuration: %s\n",
+                       ms->send_configuration ? "on" : "off");
+    monitor_hmp_printf(hmp, "  send-section-footer: %s\n",
+                       ms->send_section_footer ? "on" : "off");
+    monitor_hmp_printf(hmp, "  send-switchover-start: %s\n",
+                       ms->send_switchover_start ? "on" : "off");
+    monitor_hmp_printf(hmp, "  clear-bitmap-shift: %u\n",
+                       ms->clear_bitmap_shift);
 }
 
 static const gchar *format_time_str(uint64_t us)
@@ -68,11 +68,11 @@ static const gchar *format_time_str(uint64_t us)
     return g_strdup_printf("%"PRIu64" %s", us, units[index]);
 }
 
-static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info)
+static void migration_dump_blocktime(MonitorHMP *hmp, MigrationInfo *info)
 {
     if (info->has_postcopy_blocktime) {
-        monitor_printf(mon, "Postcopy Blocktime (ms): %" PRIu32 "\n",
-                       info->postcopy_blocktime);
+        monitor_hmp_printf(hmp, "Postcopy Blocktime (ms): %" PRIu32 "\n",
+                           info->postcopy_blocktime);
     }
 
     if (info->has_postcopy_vcpu_blocktime) {
@@ -80,25 +80,25 @@ static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info)
         const char *sep = "";
         int count = 0;
 
-        monitor_printf(mon, "Postcopy vCPU Blocktime (ms):\n [");
+        monitor_hmp_printf(hmp, "Postcopy vCPU Blocktime (ms):\n [");
 
         while (item) {
-            monitor_printf(mon, "%s%"PRIu32, sep, item->value);
+            monitor_hmp_printf(hmp, "%s%"PRIu32, sep, item->value);
             item = item->next;
             /* Each line 10 vcpu results, newline if there's more */
             sep = ((++count % 10 == 0) && item) ? ",\n  " : ", ";
         }
-        monitor_printf(mon, "]\n");
+        monitor_hmp_printf(hmp, "]\n");
     }
 
     if (info->has_postcopy_latency) {
-        monitor_printf(mon, "Postcopy Latency (ns): %" PRIu64 "\n",
-                       info->postcopy_latency);
+        monitor_hmp_printf(hmp, "Postcopy Latency (ns): %" PRIu64 "\n",
+                           info->postcopy_latency);
     }
 
     if (info->has_postcopy_non_vcpu_latency) {
-        monitor_printf(mon, "Postcopy non-vCPU Latency (ns): %" PRIu64 "\n",
-                       info->postcopy_non_vcpu_latency);
+        monitor_hmp_printf(hmp, "Postcopy non-vCPU Latency (ns): %" PRIu64 "\n",
+                           info->postcopy_non_vcpu_latency);
     }
 
     if (info->has_postcopy_vcpu_latency) {
@@ -106,29 +106,29 @@ static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info)
         const char *sep = "";
         int count = 0;
 
-        monitor_printf(mon, "Postcopy vCPU Latencies (ns):\n [");
+        monitor_hmp_printf(hmp, "Postcopy vCPU Latencies (ns):\n [");
 
         while (item) {
-            monitor_printf(mon, "%s%"PRIu64, sep, item->value);
+            monitor_hmp_printf(hmp, "%s%"PRIu64, sep, item->value);
             item = item->next;
             /* Each line 10 vcpu results, newline if there's more */
             sep = ((++count % 10 == 0) && item) ? ",\n  " : ", ";
         }
-        monitor_printf(mon, "]\n");
+        monitor_hmp_printf(hmp, "]\n");
     }
 
     if (info->has_postcopy_latency_dist) {
         uint64List *item = info->postcopy_latency_dist;
         int count = 0;
 
-        monitor_printf(mon, "Postcopy Latency Distribution:\n");
+        monitor_hmp_printf(hmp, "Postcopy Latency Distribution:\n");
 
         while (item) {
             g_autofree const gchar *from = format_time_str(1UL << count);
             g_autofree const gchar *to = format_time_str(1UL << (count + 1));
 
-            monitor_printf(mon, "  [ %8s - %8s ]: %10"PRIu64"\n",
-                           from, to, item->value);
+            monitor_hmp_printf(hmp, "  [ %8s - %8s ]: %10"PRIu64"\n",
+                               from, to, item->value);
             item = item->next;
             count++;
         }
@@ -137,7 +137,6 @@ static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info)
 
 void hmp_info_migrate(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     bool show_all = qdict_get_try_bool(qdict, "all", false);
     MigrationInfo *info;
 
@@ -145,59 +144,59 @@ void hmp_info_migrate(MonitorHMP *hmp, const QDict *qdict)
 
     if (info->blocked_reasons) {
         strList *reasons = info->blocked_reasons;
-        monitor_printf(mon, "Outgoing migration blocked:\n");
+        monitor_hmp_printf(hmp, "Outgoing migration blocked:\n");
         while (reasons) {
-            monitor_printf(mon, "  %s\n", reasons->value);
+            monitor_hmp_printf(hmp, "  %s\n", reasons->value);
             reasons = reasons->next;
         }
     }
 
     if (info->has_status) {
-        monitor_printf(mon, "Status: \t\t%s",
-                       MigrationStatus_str(info->status));
+        monitor_hmp_printf(hmp, "Status: \t\t%s",
+                           MigrationStatus_str(info->status));
         if ((info->status == MIGRATION_STATUS_FAILED ||
              info->status == MIGRATION_STATUS_POSTCOPY_PAUSED) &&
             info->error_desc) {
-            monitor_printf(mon, " (%s)\n", info->error_desc);
+            monitor_hmp_printf(hmp, " (%s)\n", info->error_desc);
         } else {
-            monitor_printf(mon, "\n");
+            monitor_hmp_printf(hmp, "\n");
         }
 
         if (info->total_time) {
-            monitor_printf(mon, "Time (ms): \t\ttotal=%" PRIu64,
-                           info->total_time);
+            monitor_hmp_printf(hmp, "Time (ms): \t\ttotal=%" PRIu64,
+                               info->total_time);
             if (info->has_setup_time) {
-                monitor_printf(mon, ", setup=%" PRIu64,
-                               info->setup_time);
+                monitor_hmp_printf(hmp, ", setup=%" PRIu64,
+                                   info->setup_time);
             }
             if (info->has_expected_downtime) {
-                monitor_printf(mon, ", exp_down=%" PRIu64,
-                               info->expected_downtime);
+                monitor_hmp_printf(hmp, ", exp_down=%" PRIu64,
+                                   info->expected_downtime);
             }
             if (info->has_downtime) {
-                monitor_printf(mon, ", down=%" PRIu64,
-                               info->downtime);
+                monitor_hmp_printf(hmp, ", down=%" PRIu64,
+                                   info->downtime);
             }
-            monitor_printf(mon, "\n");
+            monitor_hmp_printf(hmp, "\n");
         }
     }
 
     if (info->has_remaining) {
         g_autofree char *remaining = size_to_str(info->remaining);
-        monitor_printf(mon, "Remaining: \t\t%s\n", remaining);
+        monitor_hmp_printf(hmp, "Remaining: \t\t%s\n", remaining);
     }
 
     if (info->has_socket_address) {
         SocketAddressList *addr;
 
-        monitor_printf(mon, "Sockets: [\n");
+        monitor_hmp_printf(hmp, "Sockets: [\n");
 
         for (addr = info->socket_address; addr; addr = addr->next) {
             char *s = socket_uri(addr->value);
-            monitor_printf(mon, "\t%s\n", s);
+            monitor_hmp_printf(hmp, "\t%s\n", s);
             g_free(s);
         }
-        monitor_printf(mon, "]\n");
+        monitor_hmp_printf(hmp, "]\n");
     }
 
     if (info->ram) {
@@ -209,219 +208,217 @@ void hmp_info_migrate(MonitorHMP *hmp, const QDict *qdict)
         g_autofree char *str_multifd = size_to_str(info->ram->multifd_bytes);
         g_autofree char *str_postcopy = size_to_str(info->ram->postcopy_bytes);
 
-        monitor_printf(mon, "RAM info:\n");
-        monitor_printf(mon, "  Throughput (Mbps): \t%0.2f\n",
-                       info->ram->mbps);
-        monitor_printf(mon, "  Sizes: \t\tpagesize=%s, total=%s\n",
-                       str_psize, str_total);
-        monitor_printf(mon, "  Transfers: \t\ttransferred=%s, remain=%s\n",
-                       str_transferred, str_remaining);
-        monitor_printf(mon, "    Channels: \t\tprecopy=%s, "
-                       "multifd=%s, postcopy=%s",
-                       str_precopy, str_multifd, str_postcopy);
+        monitor_hmp_printf(hmp, "RAM info:\n");
+        monitor_hmp_printf(hmp, "  Throughput (Mbps): \t%0.2f\n",
+                           info->ram->mbps);
+        monitor_hmp_printf(hmp, "  Sizes: \t\tpagesize=%s, total=%s\n",
+                           str_psize, str_total);
+        monitor_hmp_printf(hmp, "  Transfers: \t\ttransferred=%s, remain=%s\n",
+                           str_transferred, str_remaining);
+        monitor_hmp_printf(hmp, "    Channels: \t\tprecopy=%s, "
+                           "multifd=%s, postcopy=%s",
+                           str_precopy, str_multifd, str_postcopy);
 
         if (info->vfio) {
             g_autofree char *str_vfio = size_to_str(info->vfio->transferred);
 
-            monitor_printf(mon, ", vfio=%s", str_vfio);
+            monitor_hmp_printf(hmp, ", vfio=%s", str_vfio);
         }
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "\n");
 
-        monitor_printf(mon, "    Page Types: \tnormal=%" PRIu64
-                       ", zero=%" PRIu64 "\n",
-                       info->ram->normal, info->ram->duplicate);
-        monitor_printf(mon, "  Page Rates (pps): \ttransfer=%" PRIu64,
-                       info->ram->pages_per_second);
+        monitor_hmp_printf(hmp, "    Page Types: \tnormal=%" PRIu64
+                           ", zero=%" PRIu64 "\n",
+                           info->ram->normal, info->ram->duplicate);
+        monitor_hmp_printf(hmp, "  Page Rates (pps): \ttransfer=%" PRIu64,
+                           info->ram->pages_per_second);
         if (info->ram->dirty_pages_rate) {
-            monitor_printf(mon, ", dirty=%" PRIu64,
-                           info->ram->dirty_pages_rate);
+            monitor_hmp_printf(hmp, ", dirty=%" PRIu64,
+                               info->ram->dirty_pages_rate);
         }
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "\n");
 
-        monitor_printf(mon, "  Others: \t\tdirty_syncs=%" PRIu64,
-                       info->ram->dirty_sync_count);
+        monitor_hmp_printf(hmp, "  Others: \t\tdirty_syncs=%" PRIu64,
+                           info->ram->dirty_sync_count);
         if (info->ram->postcopy_requests) {
-            monitor_printf(mon, ", postcopy_req=%" PRIu64,
-                           info->ram->postcopy_requests);
+            monitor_hmp_printf(hmp, ", postcopy_req=%" PRIu64,
+                               info->ram->postcopy_requests);
         }
         if (info->ram->downtime_bytes) {
-            monitor_printf(mon, ", downtime_bytes=%" PRIu64,
-                           info->ram->downtime_bytes);
+            monitor_hmp_printf(hmp, ", downtime_bytes=%" PRIu64,
+                               info->ram->downtime_bytes);
         }
         if (info->ram->dirty_sync_missed_zero_copy) {
-            monitor_printf(mon, ", zerocopy_fallbacks=%" PRIu64,
-                           info->ram->dirty_sync_missed_zero_copy);
+            monitor_hmp_printf(hmp, ", zerocopy_fallbacks=%" PRIu64,
+                               info->ram->dirty_sync_missed_zero_copy);
         }
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "\n");
     }
 
     if (!show_all) {
         goto out;
     }
 
-    migration_global_dump(mon);
+    migration_global_dump(hmp);
 
     if (info->xbzrle_cache) {
-        monitor_printf(mon, "XBZRLE: size=%" PRIu64
-                       ", transferred=%" PRIu64
-                       ", pages=%" PRIu64
-                       ", miss=%" PRIu64 "\n"
-                       "  miss_rate=%0.2f"
-                       ", encode_rate=%0.2f"
-                       ", overflow=%" PRIu64 "\n",
-                       info->xbzrle_cache->cache_size,
-                       info->xbzrle_cache->bytes,
-                       info->xbzrle_cache->pages,
-                       info->xbzrle_cache->cache_miss,
-                       info->xbzrle_cache->cache_miss_rate,
-                       info->xbzrle_cache->encoding_rate,
-                       info->xbzrle_cache->overflow);
+        monitor_hmp_printf(hmp, "XBZRLE: size=%" PRIu64
+                           ", transferred=%" PRIu64
+                           ", pages=%" PRIu64
+                           ", miss=%" PRIu64 "\n"
+                           "  miss_rate=%0.2f"
+                           ", encode_rate=%0.2f"
+                           ", overflow=%" PRIu64 "\n",
+                           info->xbzrle_cache->cache_size,
+                           info->xbzrle_cache->bytes,
+                           info->xbzrle_cache->pages,
+                           info->xbzrle_cache->cache_miss,
+                           info->xbzrle_cache->cache_miss_rate,
+                           info->xbzrle_cache->encoding_rate,
+                           info->xbzrle_cache->overflow);
     }
 
     if (info->has_cpu_throttle_percentage) {
-        monitor_printf(mon, "CPU Throttle (%%): %" PRIu64 "\n",
-                       info->cpu_throttle_percentage);
+        monitor_hmp_printf(hmp, "CPU Throttle (%%): %" PRIu64 "\n",
+                           info->cpu_throttle_percentage);
     }
 
     if (info->has_dirty_limit_throttle_time_per_round) {
-        monitor_printf(mon, "Dirty-limit Throttle (us): %" PRIu64 "\n",
-                       info->dirty_limit_throttle_time_per_round);
+        monitor_hmp_printf(hmp, "Dirty-limit Throttle (us): %" PRIu64 "\n",
+                           info->dirty_limit_throttle_time_per_round);
     }
 
     if (info->has_dirty_limit_ring_full_time) {
-        monitor_printf(mon, "Dirty-limit Ring Full (us): %" PRIu64 "\n",
-                       info->dirty_limit_ring_full_time);
+        monitor_hmp_printf(hmp, "Dirty-limit Ring Full (us): %" PRIu64 "\n",
+                           info->dirty_limit_ring_full_time);
     }
 
-    migration_dump_blocktime(mon, info);
+    migration_dump_blocktime(hmp, info);
 out:
     qapi_free_MigrationInfo(info);
 }
 
 void hmp_info_migrate_capabilities(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     MigrationCapabilityStatusList *caps, *cap;
 
     caps = qmp_query_migrate_capabilities(NULL);
 
     if (caps) {
         for (cap = caps; cap; cap = cap->next) {
-            monitor_printf(mon, "%s: %s\n",
-                           MigrationCapability_str(cap->value->capability),
-                           cap->value->state ? "on" : "off");
+            monitor_hmp_printf(hmp, "%s: %s\n",
+                               MigrationCapability_str(cap->value->capability),
+                               cap->value->state ? "on" : "off");
         }
     }
 
     qapi_free_MigrationCapabilityStatusList(caps);
 }
 
-static void monitor_print_cpr_exec_command(Monitor *mon, strList *args)
+static void monitor_print_cpr_exec_command(MonitorHMP *hmp, strList *args)
 {
-    monitor_printf(mon, "%s:",
+    monitor_hmp_printf(hmp, "%s:",
         MigrationParameter_str(MIGRATION_PARAMETER_CPR_EXEC_COMMAND));
 
     while (args) {
-        monitor_printf(mon, " %s", args->value);
+        monitor_hmp_printf(hmp, " %s", args->value);
         args = args->next;
     }
-    monitor_printf(mon, "\n");
+    monitor_hmp_printf(hmp, "\n");
 }
 
 void hmp_info_migrate_parameters(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     MigrationParameters *params;
     MigrationState *s = migrate_get_current();
 
     params = qmp_query_migrate_parameters(NULL);
 
     if (params) {
-        monitor_printf(mon, "%s: %" PRIu64 " ms\n",
+        monitor_hmp_printf(hmp, "%s: %" PRIu64 " ms\n",
             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_INITIAL),
             params->announce_initial);
-        monitor_printf(mon, "%s: %" PRIu64 " ms\n",
+        monitor_hmp_printf(hmp, "%s: %" PRIu64 " ms\n",
             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_MAX),
             params->announce_max);
-        monitor_printf(mon, "%s: %" PRIu64 "\n",
+        monitor_hmp_printf(hmp, "%s: %" PRIu64 "\n",
             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_ROUNDS),
             params->announce_rounds);
-        monitor_printf(mon, "%s: %" PRIu64 " ms\n",
+        monitor_hmp_printf(hmp, "%s: %" PRIu64 " ms\n",
             MigrationParameter_str(MIGRATION_PARAMETER_ANNOUNCE_STEP),
             params->announce_step);
         assert(params->has_throttle_trigger_threshold);
-        monitor_printf(mon, "%s: %u\n",
+        monitor_hmp_printf(hmp, "%s: %u\n",
             MigrationParameter_str(MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD),
             params->throttle_trigger_threshold);
         assert(params->has_cpu_throttle_initial);
-        monitor_printf(mon, "%s: %u\n",
+        monitor_hmp_printf(hmp, "%s: %u\n",
             MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL),
             params->cpu_throttle_initial);
         assert(params->has_cpu_throttle_increment);
-        monitor_printf(mon, "%s: %u\n",
+        monitor_hmp_printf(hmp, "%s: %u\n",
             MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT),
             params->cpu_throttle_increment);
         assert(params->has_cpu_throttle_tailslow);
-        monitor_printf(mon, "%s: %s\n",
+        monitor_hmp_printf(hmp, "%s: %s\n",
             MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_TAILSLOW),
             params->cpu_throttle_tailslow ? "on" : "off");
         assert(params->has_max_cpu_throttle);
-        monitor_printf(mon, "%s: %u\n",
+        monitor_hmp_printf(hmp, "%s: %u\n",
             MigrationParameter_str(MIGRATION_PARAMETER_MAX_CPU_THROTTLE),
             params->max_cpu_throttle);
         assert(params->tls_creds);
-        monitor_printf(mon, "%s: '%s'\n",
+        monitor_hmp_printf(hmp, "%s: '%s'\n",
             MigrationParameter_str(MIGRATION_PARAMETER_TLS_CREDS),
                        params->tls_creds->u.s);
         assert(params->tls_hostname);
-        monitor_printf(mon, "%s: '%s'\n",
+        monitor_hmp_printf(hmp, "%s: '%s'\n",
             MigrationParameter_str(MIGRATION_PARAMETER_TLS_HOSTNAME),
                        params->tls_hostname->u.s);
         assert(params->tls_authz);
-        monitor_printf(mon, "%s: '%s'\n",
+        monitor_hmp_printf(hmp, "%s: '%s'\n",
             MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ),
                        params->tls_authz->u.s);
         assert(params->has_max_bandwidth);
-        monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n",
+        monitor_hmp_printf(hmp, "%s: %" PRIu64 " bytes/second\n",
             MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH),
             params->max_bandwidth);
         assert(params->has_avail_switchover_bandwidth);
-        monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n",
+        monitor_hmp_printf(hmp, "%s: %" PRIu64 " bytes/second\n",
             MigrationParameter_str(MIGRATION_PARAMETER_AVAIL_SWITCHOVER_BANDWIDTH),
             params->avail_switchover_bandwidth);
         assert(params->has_max_postcopy_bandwidth);
-        monitor_printf(mon, "%s: %" PRIu64 " bytes/second\n",
+        monitor_hmp_printf(hmp, "%s: %" PRIu64 " bytes/second\n",
             MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH),
             params->max_postcopy_bandwidth);
         assert(params->has_downtime_limit);
-        monitor_printf(mon, "%s: %" PRIu64 " ms\n",
+        monitor_hmp_printf(hmp, "%s: %" PRIu64 " ms\n",
             MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT),
             params->downtime_limit);
         assert(params->has_x_checkpoint_delay);
-        monitor_printf(mon, "%s: %u ms\n",
+        monitor_hmp_printf(hmp, "%s: %u ms\n",
             MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY),
             params->x_checkpoint_delay);
-        monitor_printf(mon, "%s: %u\n",
+        monitor_hmp_printf(hmp, "%s: %u\n",
             MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_CHANNELS),
             params->multifd_channels);
-        monitor_printf(mon, "%s: %s\n",
+        monitor_hmp_printf(hmp, "%s: %s\n",
             MigrationParameter_str(MIGRATION_PARAMETER_MULTIFD_COMPRESSION),
             MultiFDCompression_str(params->multifd_compression));
         assert(params->has_zero_page_detection);
-        monitor_printf(mon, "%s: %s\n",
+        monitor_hmp_printf(hmp, "%s: %s\n",
             MigrationParameter_str(MIGRATION_PARAMETER_ZERO_PAGE_DETECTION),
             qapi_enum_lookup(&ZeroPageDetection_lookup,
                 params->zero_page_detection));
-        monitor_printf(mon, "%s: %" PRIu64 " bytes\n",
+        monitor_hmp_printf(hmp, "%s: %" PRIu64 " bytes\n",
             MigrationParameter_str(MIGRATION_PARAMETER_XBZRLE_CACHE_SIZE),
             params->xbzrle_cache_size);
 
         if (s->has_block_bitmap_mapping) {
             const BitmapMigrationNodeAliasList *bmnal;
 
-            monitor_printf(mon, "%s:\n",
-                           MigrationParameter_str(
-                               MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING));
+            monitor_hmp_printf(hmp, "%s:\n",
+                               MigrationParameter_str(
+                                   MIGRATION_PARAMETER_BLOCK_BITMAP_MAPPING));
 
             for (bmnal = params->block_bitmap_mapping;
                  bmnal;
@@ -430,47 +427,47 @@ void hmp_info_migrate_parameters(MonitorHMP *hmp, const QDict *qdict)
                 const BitmapMigrationNodeAlias *bmna = bmnal->value;
                 const BitmapMigrationBitmapAliasList *bmbal;
 
-                monitor_printf(mon, "  '%s' -> '%s'\n",
-                               bmna->node_name, bmna->alias);
+                monitor_hmp_printf(hmp, "  '%s' -> '%s'\n",
+                                   bmna->node_name, bmna->alias);
 
                 for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) {
                     const BitmapMigrationBitmapAlias *bmba = bmbal->value;
 
-                    monitor_printf(mon, "    '%s' -> '%s'\n",
-                                   bmba->name, bmba->alias);
+                    monitor_hmp_printf(hmp, "    '%s' -> '%s'\n",
+                                       bmba->name, bmba->alias);
                 }
             }
         }
 
-        monitor_printf(mon, "%s: %" PRIu64 " ms\n",
+        monitor_hmp_printf(hmp, "%s: %" PRIu64 " ms\n",
         MigrationParameter_str(MIGRATION_PARAMETER_X_VCPU_DIRTY_LIMIT_PERIOD),
         params->x_vcpu_dirty_limit_period);
 
-        monitor_printf(mon, "%s: %" PRIu64 " MB/s\n",
+        monitor_hmp_printf(hmp, "%s: %" PRIu64 " MB/s\n",
             MigrationParameter_str(MIGRATION_PARAMETER_VCPU_DIRTY_LIMIT),
             params->vcpu_dirty_limit);
 
         assert(params->has_mode);
-        monitor_printf(mon, "%s: %s\n",
+        monitor_hmp_printf(hmp, "%s: %s\n",
             MigrationParameter_str(MIGRATION_PARAMETER_MODE),
             qapi_enum_lookup(&MigMode_lookup, params->mode));
 
         if (params->has_direct_io) {
-            monitor_printf(mon, "%s: %s\n",
-                           MigrationParameter_str(
-                               MIGRATION_PARAMETER_DIRECT_IO),
-                           params->direct_io ? "on" : "off");
+            monitor_hmp_printf(hmp, "%s: %s\n",
+                               MigrationParameter_str(
+                                   MIGRATION_PARAMETER_DIRECT_IO),
+                               params->direct_io ? "on" : "off");
         }
 
         if (params->has_x_rdma_chunk_size) {
-            monitor_printf(mon, "%s: %" PRIu64 " bytes\n",
-                           MigrationParameter_str(
-                               MIGRATION_PARAMETER_X_RDMA_CHUNK_SIZE),
-                           params->x_rdma_chunk_size);
+            monitor_hmp_printf(hmp, "%s: %" PRIu64 " bytes\n",
+                               MigrationParameter_str(
+                                   MIGRATION_PARAMETER_X_RDMA_CHUNK_SIZE),
+                               params->x_rdma_chunk_size);
         }
 
         assert(params->has_cpr_exec_command);
-        monitor_print_cpr_exec_command(mon, params->cpr_exec_command);
+        monitor_print_cpr_exec_command(hmp, params->cpr_exec_command);
     }
 
     qapi_free_MigrationParameters(params);
@@ -857,12 +854,12 @@ void hmp_migrate(MonitorHMP *hmp, const QDict *qdict)
     if (uri_cpr) {
         if (migrate_mode() != MIG_MODE_CPR_TRANSFER) {
             error_setg(&err, "-c can only be used in cpr-transfer mode");
-            hmp_handle_error(mon, err);
+            hmp_handle_error(hmp, err);
             return;
         }
 
         if (!migrate_uri_parse(uri_cpr, &channel_cpr, &err)) {
-            hmp_handle_error(mon, err);
+            hmp_handle_error(hmp, err);
             return;
         }
 
@@ -879,8 +876,8 @@ void hmp_migrate(MonitorHMP *hmp, const QDict *qdict)
         HMPMigrationStatus *status;
 
         if (!hmp->use_readline) {
-            monitor_printf(mon, "terminal does not allow synchronous "
-                           "migration, continuing detached\n");
+            monitor_hmp_printf(hmp, "terminal does not allow synchronous "
+                               "migration, continuing detached\n");
             return;
         }
         monitor_suspend(mon);
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 89cc19c2431d..1834e3c1f697 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -105,26 +105,24 @@ strList *hmp_split_at_comma(const char *str)
 
 void hmp_info_name(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     NameInfo *info;
 
     info = qmp_query_name(NULL);
     if (info->name) {
-        monitor_printf(mon, "%s\n", info->name);
+        monitor_hmp_printf(hmp, "%s\n", info->name);
     }
     qapi_free_NameInfo(info);
 }
 
 void hmp_info_version(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     VersionInfo *info;
 
     info = qmp_query_version(NULL);
 
-    monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n",
-                   info->qemu->major, info->qemu->minor, info->qemu->micro,
-                   info->package);
+    monitor_hmp_printf(hmp, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n",
+                       info->qemu->major, info->qemu->minor, info->qemu->micro,
+                       info->package);
 
     qapi_free_VersionInfo(info);
 }
@@ -145,13 +143,12 @@ void hmp_stop(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_sync_profile(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *op = qdict_get_try_str(qdict, "op");
 
     if (op == NULL) {
         bool on = qsp_is_enabled();
 
-        monitor_printf(mon, "sync-profile is %s\n", on ? "on" : "off");
+        monitor_hmp_printf(hmp, "sync-profile is %s\n", on ? "on" : "off");
         return;
     }
     if (!strcmp(op, "on")) {
@@ -179,14 +176,13 @@ void hmp_exit_preconfig(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_cpu(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int64_t cpu_index;
 
     /* XXX: drop the monitor_hmp_set_cpu() usage when all HMP commands that
             use it are converted to the QAPI */
     cpu_index = qdict_get_int(qdict, "index");
     if (monitor_hmp_set_cpu(hmp, cpu_index) < 0) {
-        monitor_printf(mon, "invalid CPU index\n");
+        monitor_hmp_printf(hmp, "invalid CPU index\n");
     }
 }
 
@@ -200,7 +196,6 @@ void hmp_cont(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_change(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *device = qdict_get_str(qdict, "device");
     const char *target = qdict_get_str(qdict, "target");
     const char *arg = qdict_get_try_str(qdict, "arg");
@@ -210,11 +205,11 @@ void hmp_change(MonitorHMP *hmp, const QDict *qdict)
 
 #ifdef CONFIG_VNC
     if (strcmp(device, "vnc") == 0) {
-        hmp_change_vnc(mon, device, target, arg, read_only, force, &err);
+        hmp_change_vnc(hmp, device, target, arg, read_only, force, &err);
     } else
 #endif
     {
-        hmp_change_medium(mon, device, target, arg, read_only, force, &err);
+        hmp_change_medium(hmp, device, target, arg, read_only, force, &err);
     }
 
     hmp_handle_error(hmp, err);
@@ -242,21 +237,20 @@ void hmp_closefd(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_iothreads(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
     IOThreadInfoList *info;
     IOThreadInfo *value;
 
     for (info = info_list; info; info = info->next) {
         value = info->value;
-        monitor_printf(mon, "%s:\n", value->id);
-        monitor_printf(mon, "  thread_id=%" PRId64 "\n", value->thread_id);
-        monitor_printf(mon, "  poll-max-ns=%" PRId64 "\n", value->poll_max_ns);
-        monitor_printf(mon, "  poll-grow=%" PRId64 "\n", value->poll_grow);
-        monitor_printf(mon, "  poll-shrink=%" PRId64 "\n", value->poll_shrink);
-        monitor_printf(mon, "  poll-weight=%" PRId64 "\n", value->poll_weight);
-        monitor_printf(mon, "  aio-max-batch=%" PRId64 "\n",
-                       value->aio_max_batch);
+        monitor_hmp_printf(hmp, "%s:\n", value->id);
+        monitor_hmp_printf(hmp, "  thread_id=%" PRId64 "\n", value->thread_id);
+        monitor_hmp_printf(hmp, "  poll-max-ns=%" PRId64 "\n", value->poll_max_ns);
+        monitor_hmp_printf(hmp, "  poll-grow=%" PRId64 "\n", value->poll_grow);
+        monitor_hmp_printf(hmp, "  poll-shrink=%" PRId64 "\n", value->poll_shrink);
+        monitor_hmp_printf(hmp, "  poll-weight=%" PRId64 "\n", value->poll_weight);
+        monitor_hmp_printf(hmp, "  aio-max-batch=%" PRId64 "\n",
+                           value->aio_max_batch);
     }
 
     qapi_free_IOThreadInfoList(info_list);
@@ -264,26 +258,23 @@ void hmp_info_iothreads(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_help(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
-    hmp_help_cmd(mon, qdict_get_try_str(qdict, "name"));
+    hmp_help_cmd(hmp, qdict_get_try_str(qdict, "name"));
 }
 
 void hmp_clear(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     /*
      * Send an ANSI escape sequence:
      * "\x1b[H" - move cursor to top-left
      * "\x1b[2J" - clear visible screen
      * "\x1b[3J" - clear scrollback
      */
-    monitor_printf(mon, "\x1b[H\x1b[2J\x1b[3J");
+    monitor_hmp_printf(hmp, "\x1b[H\x1b[2J\x1b[3J");
 }
 
 void hmp_info_help(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
-    hmp_help_cmd(mon, "info");
+    hmp_help_cmd(hmp, "info");
 }
 
 void hmp_info_sync_profile(MonitorHMP *hmp, const QDict *qdict)
@@ -299,7 +290,6 @@ void hmp_info_sync_profile(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_history(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int i;
     const char *str;
 
@@ -312,7 +302,7 @@ void hmp_info_history(MonitorHMP *hmp, const QDict *qdict)
         if (!str) {
             break;
         }
-        monitor_printf(mon, "%d: '%s'\n", i, str);
+        monitor_hmp_printf(hmp, "%d: '%s'\n", i, str);
         i++;
     }
 }
@@ -328,7 +318,6 @@ void hmp_logfile(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_log(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int mask;
     const char *items = qdict_get_str(qdict, "items");
     Error *err = NULL;
@@ -338,7 +327,7 @@ void hmp_log(MonitorHMP *hmp, const QDict *qdict)
     } else {
         mask = qemu_str_to_log_mask(items);
         if (!mask) {
-            hmp_help_cmd(mon, "log");
+            hmp_help_cmd(hmp, "log");
             return;
         }
     }
@@ -350,7 +339,6 @@ void hmp_log(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_gdbserver(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     const char *device = qdict_get_try_str(qdict, "device");
 
@@ -361,43 +349,41 @@ void hmp_gdbserver(MonitorHMP *hmp, const QDict *qdict)
     if (!gdbserver_start(device, &err)) {
         error_report_err(err);
     } else if (strcmp(device, "none") == 0) {
-        monitor_printf(mon, "Disabled gdbserver\n");
+        monitor_hmp_printf(hmp, "Disabled gdbserver\n");
     } else {
-        monitor_printf(mon, "Waiting for gdb connection on device '%s'\n",
-                       device);
+        monitor_hmp_printf(hmp, "Waiting for gdb connection on device '%s'\n",
+                           device);
     }
 }
 
 void hmp_print(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int format = qdict_get_int(qdict, "format");
     hwaddr val = qdict_get_int(qdict, "val");
 
     switch(format) {
     case 'o':
-        monitor_printf(mon, "%#" HWADDR_PRIo, val);
+        monitor_hmp_printf(hmp, "0x%" HWADDR_PRIo, val);
         break;
     case 'x':
-        monitor_printf(mon, "%#" HWADDR_PRIx, val);
+        monitor_hmp_printf(hmp, "0x%" HWADDR_PRIx, val);
         break;
     case 'u':
-        monitor_printf(mon, "%" HWADDR_PRIu, val);
+        monitor_hmp_printf(hmp, "%" HWADDR_PRIu, val);
         break;
     default:
     case 'd':
-        monitor_printf(mon, "%" HWADDR_PRId, val);
+        monitor_hmp_printf(hmp, "%" HWADDR_PRId, val);
         break;
     case 'c':
-        monitor_printc(mon, val);
+        monitor_hmp_printc(hmp, val);
         break;
     }
-    monitor_printf(mon, "\n");
+    monitor_hmp_printf(hmp, "\n");
 }
 
 void hmp_sum(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     uint32_t addr;
     uint16_t sum;
     uint32_t start = qdict_get_int(qdict, "start");
@@ -411,12 +397,11 @@ void hmp_sum(MonitorHMP *hmp, const QDict *qdict)
         sum = (sum >> 1) | (sum << 15);
         sum += val;
     }
-    monitor_printf(mon, "%05d\n", sum);
+    monitor_hmp_printf(hmp, "%05d\n", sum);
 }
 
 void hmp_ioport_read(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int size = qdict_get_int(qdict, "size");
     int addr = qdict_get_int(qdict, "addr");
     int has_index = qdict_haskey(qdict, "index");
@@ -445,8 +430,8 @@ void hmp_ioport_read(MonitorHMP *hmp, const QDict *qdict)
         suffix = 'l';
         break;
     }
-    monitor_printf(mon, "port%c[0x%04x] = 0x%0*x\n",
-                   suffix, addr, size * 2, val);
+    monitor_hmp_printf(hmp, "port%c[0x%04x] = 0x%0*x\n",
+                       suffix, addr, size * 2, val);
 }
 
 void hmp_ioport_write(MonitorHMP *hmp, const QDict *qdict)
@@ -473,7 +458,6 @@ void hmp_ioport_write(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_boot_set(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *local_err = NULL;
     const char *bootdevice = qdict_get_str(qdict, "bootdevice");
 
@@ -481,7 +465,7 @@ void hmp_boot_set(MonitorHMP *hmp, const QDict *qdict)
     if (local_err) {
         error_report_err(local_err);
     } else {
-        monitor_printf(mon, "boot device list now set to %s\n", bootdevice);
+        monitor_hmp_printf(hmp, "boot device list now set to %s\n", bootdevice);
     }
 }
 
@@ -507,7 +491,7 @@ void hmp_dumpdtb(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(MONITOR(hmp), "DTB dumped to '%s'\n", filename);
+    monitor_hmp_printf(hmp, "DTB dumped to '%s'\n", filename);
 }
 #endif
 
@@ -573,14 +557,13 @@ int monitor_hmp_get_cpu_index(MonitorHMP *hmp)
 
 void hmp_info_registers(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     bool all_cpus = qdict_get_try_bool(qdict, "cpustate_all", false);
     int vcpu = qdict_get_try_int(qdict, "vcpu", -1);
     CPUState *cs;
 
     if (all_cpus) {
         CPU_FOREACH(cs) {
-            monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
+            monitor_hmp_printf(hmp, "\nCPU#%d\n", cs->cpu_index);
             cpu_dump_state(cs, NULL, CPU_DUMP_FPU | CPU_DUMP_VPU);
         }
     } else {
@@ -588,14 +571,14 @@ void hmp_info_registers(MonitorHMP *hmp, const QDict *qdict)
 
         if (!cs) {
             if (vcpu >= 0) {
-                monitor_printf(mon, "CPU#%d not available\n", vcpu);
+                monitor_hmp_printf(hmp, "CPU#%d not available\n", vcpu);
             } else {
-                monitor_printf(mon, "No CPU available\n");
+                monitor_hmp_printf(hmp, "No CPU available\n");
             }
             return;
         }
 
-        monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
+        monitor_hmp_printf(hmp, "\nCPU#%d\n", cs->cpu_index);
         cpu_dump_state(cs, NULL, CPU_DUMP_FPU | CPU_DUMP_VPU);
     }
 }
@@ -603,7 +586,6 @@ void hmp_info_registers(MonitorHMP *hmp, const QDict *qdict)
 static void memory_dump(MonitorHMP *hmp, int count, int format, int wsize,
                         uint64_t addr, bool is_physical)
 {
-    Monitor *mon = MONITOR(hmp);
     int l, line_size, i, max_digits, len;
     uint8_t buf[16];
     uint64_t v;
@@ -612,12 +594,12 @@ static void memory_dump(MonitorHMP *hmp, int count, int format, int wsize,
     const bool big_endian = target_big_endian();
 
     if (!cs && (format == 'i' || !is_physical)) {
-        monitor_printf(mon, "Can not dump without CPU\n");
+        monitor_hmp_printf(hmp, "Can not dump without CPU\n");
         return;
     }
 
     if (format == 'i') {
-        monitor_disas(mon, cs, addr, count, is_physical);
+        monitor_disas(hmp, cs, addr, count, is_physical);
         return;
     }
 
@@ -647,7 +629,7 @@ static void memory_dump(MonitorHMP *hmp, int count, int format, int wsize,
     }
 
     while (len > 0) {
-        monitor_printf(mon, "%0*" PRIx64 ":", addr_width, addr);
+        monitor_hmp_printf(hmp, "%0*" PRIx64 ":", addr_width, addr);
         l = len;
         if (l > line_size) {
             l = line_size;
@@ -657,12 +639,12 @@ static void memory_dump(MonitorHMP *hmp, int count, int format, int wsize,
             MemTxResult r = address_space_read(as, addr,
                                                MEMTXATTRS_UNSPECIFIED, buf, l);
             if (r != MEMTX_OK) {
-                monitor_printf(mon, " Cannot access memory\n");
+                monitor_hmp_printf(hmp, " Cannot access memory\n");
                 break;
             }
         } else {
             if (cpu_memory_rw_debug(cs, addr, buf, l, 0) < 0) {
-                monitor_printf(mon, " Cannot access memory\n");
+                monitor_hmp_printf(hmp, " Cannot access memory\n");
                 break;
             }
         }
@@ -683,27 +665,27 @@ static void memory_dump(MonitorHMP *hmp, int count, int format, int wsize,
                 v = (big_endian ? ldq_be_p : ldq_le_p)(buf + i);
                 break;
             }
-            monitor_printf(mon, " ");
+            monitor_hmp_printf(hmp, " ");
             switch (format) {
             case 'o':
-                monitor_printf(mon, "0%*" PRIo64, max_digits, v);
+                monitor_hmp_printf(hmp, "0%*" PRIo64, max_digits, v);
                 break;
             case 'x':
-                monitor_printf(mon, "0x%0*" PRIx64, max_digits, v);
+                monitor_hmp_printf(hmp, "0x%0*" PRIx64, max_digits, v);
                 break;
             case 'u':
-                monitor_printf(mon, "%*" PRIu64, max_digits, v);
+                monitor_hmp_printf(hmp, "%*" PRIu64, max_digits, v);
                 break;
             case 'd':
-                monitor_printf(mon, "%*" PRId64, max_digits, v);
+                monitor_hmp_printf(hmp, "%*" PRId64, max_digits, v);
                 break;
             case 'c':
-                monitor_printc(mon, v);
+                monitor_hmp_printc(hmp, v);
                 break;
             }
             i += wsize;
         }
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "\n");
         addr += l;
         len -= l;
     }
@@ -731,7 +713,6 @@ void hmp_physical_memory_dump(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_gpa2hva(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     hwaddr addr = qdict_get_int(qdict, "addr");
     Error *local_err = NULL;
     MemoryRegion *mr = NULL;
@@ -743,29 +724,28 @@ void hmp_gpa2hva(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "Host virtual address for 0x%" HWADDR_PRIx
-                   " (%s) is %p\n",
-                   addr, mr->name, ptr);
+    monitor_hmp_printf(hmp, "Host virtual address for 0x%" HWADDR_PRIx
+                       " (%s) is %p\n",
+                       addr, mr->name, ptr);
 
     memory_region_unref(mr);
 }
 
 void hmp_gva2gpa(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     vaddr addr = qdict_get_int(qdict, "addr");
     CPUState *cs = monitor_hmp_get_cpu(hmp);
     TranslateForDebugResult tres;
 
     if (!cs) {
-        monitor_printf(mon, "No cpu\n");
+        monitor_hmp_printf(hmp, "No cpu\n");
         return;
     }
 
     if (!cpu_translate_for_debug(cs, addr, &tres)) {
-        monitor_printf(mon, "Unmapped\n");
+        monitor_hmp_printf(hmp, "Unmapped\n");
     } else {
-        monitor_printf(mon, "gpa: 0x%" HWADDR_PRIx "\n", tres.physaddr);
+        monitor_hmp_printf(hmp, "gpa: 0x%" HWADDR_PRIx "\n", tres.physaddr);
     }
 }
 
@@ -806,7 +786,6 @@ out:
 
 void hmp_gpa2hpa(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     hwaddr addr = qdict_get_int(qdict, "addr");
     Error *local_err = NULL;
     MemoryRegion *mr = NULL;
@@ -823,9 +802,9 @@ void hmp_gpa2hpa(MonitorHMP *hmp, const QDict *qdict)
     if (local_err) {
         error_report_err(local_err);
     } else {
-        monitor_printf(mon, "Host physical address for 0x%" HWADDR_PRIx
-                       " (%s) is 0x%" PRIx64 "\n",
-                       addr, mr->name, (uint64_t) physaddr);
+        monitor_hmp_printf(hmp, "Host physical address for 0x%" HWADDR_PRIx
+                           " (%s) is 0x%" PRIx64 "\n",
+                           addr, mr->name, (uint64_t) physaddr);
     }
 
     memory_region_unref(mr);
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 2484a2310dff..e5f8b9c576e0 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -80,8 +80,6 @@ static void monitor_hmp_set_readline(Object *obj, bool val, Error **errp)
     hmp->use_readline = val;
 }
 
-int monitor_hmp_vprintf(Monitor *mon, const char *fmt, va_list ap)
-    G_GNUC_PRINTF(2, 0);
 static void monitor_hmp_accept_input(Monitor *mon);
 static void monitor_hmp_complete(UserCreatable *uc, Error **errp);
 static bool monitor_hmp_prepare_delete(UserCreatable *uc, Error **errp);
@@ -95,7 +93,6 @@ static void monitor_hmp_class_init(ObjectClass *cls, const void *data)
                                    monitor_hmp_get_readline,
                                    monitor_hmp_set_readline);
 
-    moncls->vprintf = monitor_hmp_vprintf;
     moncls->accept_input = monitor_hmp_accept_input;
 
     ucc->complete = monitor_hmp_complete;
@@ -114,12 +111,6 @@ static void monitor_hmp_init(Object *obj)
     hmp->use_readline = true;
 }
 
-int monitor_hmp_vprintf(Monitor *mon, const char *fmt, va_list ap)
-{
-    g_autofree char *buf = g_strdup_vprintf(fmt, ap);
-    return monitor_puts(mon, buf);
-}
-
 static void monitor_hmp_accept_input(Monitor *mon)
 {
     qemu_mutex_lock(&mon->mon_lock);
@@ -166,8 +157,7 @@ int monitor_hmp_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
         /* prompt is printed on return from the command handler */
         return 0;
     } else {
-        monitor_printf(&hmp->parent_obj,
-                       "terminal does not support password prompting\n");
+        monitor_hmp_printf(hmp, "terminal does not support password prompting\n");
         return -ENOTTY;
     }
 }
@@ -319,7 +309,7 @@ static bool cmd_available(const HMPCommand *cmd)
     return phase_check(PHASE_MACHINE_READY) || cmd_can_preconfig(cmd);
 }
 
-static void help_cmd_dump_one(Monitor *mon,
+static void help_cmd_dump_one(MonitorHMP *mon,
                               const HMPCommand *cmd,
                               char **prefix_args,
                               int prefix_args_nb)
@@ -331,13 +321,13 @@ static void help_cmd_dump_one(Monitor *mon,
     }
 
     for (i = 0; i < prefix_args_nb; i++) {
-        monitor_printf(mon, "%s ", prefix_args[i]);
+        monitor_hmp_printf(mon, "%s ", prefix_args[i]);
     }
-    monitor_printf(mon, "%s %s -- %s\n", cmd->name, cmd->params, cmd->help);
+    monitor_hmp_printf(mon, "%s %s -- %s\n", cmd->name, cmd->params, cmd->help);
 }
 
 /* @args[@arg_index] is the valid command need to find in @cmds */
-static void help_cmd_dump(Monitor *mon, const HMPCommand *cmds,
+static void help_cmd_dump(MonitorHMP *mon, const HMPCommand *cmds,
                           char **args, int nb_args, int arg_index)
 {
     const HMPCommand *cmd;
@@ -367,13 +357,13 @@ static void help_cmd_dump(Monitor *mon, const HMPCommand *cmds,
     }
 
     /* Command not found */
-    monitor_printf(mon, "unknown command: '");
+    monitor_hmp_printf(mon, "unknown command: '");
     for (i = 0; i <= arg_index; i++) {
-        monitor_printf(mon, "%s%s", args[i], i == arg_index ? "'\n" : " ");
+        monitor_hmp_printf(mon, "%s%s", args[i], i == arg_index ? "'\n" : " ");
     }
 }
 
-void hmp_help_cmd(Monitor *mon, const char *name)
+void hmp_help_cmd(MonitorHMP *mon, const char *name)
 {
     char *args[MAX_ARGS];
     int nb_args = 0;
@@ -383,15 +373,15 @@ void hmp_help_cmd(Monitor *mon, const char *name)
         /* special case for log, directly dump and return */
         if (!strcmp(name, "log")) {
             const QEMULogItem *item;
-            monitor_printf(mon, "Log items (comma separated):\n");
-            monitor_printf(mon, "%-15s %s\n", "none", "remove all logs");
+            monitor_hmp_printf(mon, "Log items (comma separated):\n");
+            monitor_hmp_printf(mon, "%-15s %s\n", "none", "remove all logs");
             for (item = qemu_log_items; item->mask != 0; item++) {
-                monitor_printf(mon, "%-15s %s\n", item->name, item->help);
+                monitor_hmp_printf(mon, "%-15s %s\n", item->name, item->help);
             }
 #ifdef CONFIG_TRACE_LOG
-            monitor_printf(mon, "trace:PATTERN   enable trace events\n");
-            monitor_printf(mon, "\nUse \"log trace:help\" to get a list of "
-                           "trace events.\n\n");
+            monitor_hmp_printf(mon, "trace:PATTERN   enable trace events\n");
+            monitor_hmp_printf(mon, "\nUse \"log trace:help\" to get a list of "
+                               "trace events.\n\n");
 #endif
             return;
         }
@@ -455,12 +445,12 @@ static sigjmp_buf expr_env;
 static int get_monitor_def(MonitorHMP *mon, int64_t *pval, const char *name);
 
 static G_NORETURN G_GNUC_PRINTF(2, 3)
-void expr_error(Monitor *mon, const char *fmt, ...)
+void expr_error(MonitorHMP *mon, const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
-    monitor_vprintf(mon, fmt, ap);
-    monitor_printf(mon, "\n");
+    monitor_hmp_vprintf(mon, fmt, ap);
+    monitor_hmp_printf(mon, "\n");
     va_end(ap);
     siglongjmp(expr_env, 1);
 }
@@ -475,9 +465,9 @@ static void next(void)
     }
 }
 
-static int64_t expr_sum(Monitor *mon);
+static int64_t expr_sum(MonitorHMP *mon);
 
-static int64_t expr_unary(Monitor *mon)
+static int64_t expr_unary(MonitorHMP *mon)
 {
     int64_t n;
     char *p;
@@ -535,8 +525,8 @@ static int64_t expr_unary(Monitor *mon)
                 pch++;
             }
             *q = 0;
-            if (!gdb_get_register(MONITOR_HMP(mon), &reg, buf)
-                && get_monitor_def(MONITOR_HMP(mon), &reg, buf) < 0) {
+            if (!gdb_get_register(mon, &reg, buf)
+                && get_monitor_def(mon, &reg, buf) < 0) {
                 expr_error(mon, "unknown register");
             }
             n = reg;
@@ -564,7 +554,7 @@ static int64_t expr_unary(Monitor *mon)
     return n;
 }
 
-static int64_t expr_prod(Monitor *mon)
+static int64_t expr_prod(MonitorHMP *mon)
 {
     int64_t val, val2;
     int op;
@@ -598,7 +588,7 @@ static int64_t expr_prod(Monitor *mon)
     return val;
 }
 
-static int64_t expr_logic(Monitor *mon)
+static int64_t expr_logic(MonitorHMP *mon)
 {
     int64_t val, val2;
     int op;
@@ -627,7 +617,7 @@ static int64_t expr_logic(Monitor *mon)
     return val;
 }
 
-static int64_t expr_sum(Monitor *mon)
+static int64_t expr_sum(MonitorHMP *mon)
 {
     int64_t val, val2;
     int op;
@@ -649,7 +639,7 @@ static int64_t expr_sum(Monitor *mon)
     return val;
 }
 
-static int get_expr(Monitor *mon, int64_t *pval, const char **pp)
+static int get_expr(MonitorHMP *mon, int64_t *pval, const char **pp)
 {
     pch = *pp;
     if (sigsetjmp(expr_env, 0)) {
@@ -664,7 +654,7 @@ static int get_expr(Monitor *mon, int64_t *pval, const char **pp)
     return 0;
 }
 
-static int get_double(Monitor *mon, double *pval, const char **pp)
+static int get_double(MonitorHMP *mon, double *pval, const char **pp)
 {
     const char *p = *pp;
     char *tailp;
@@ -672,12 +662,12 @@ static int get_double(Monitor *mon, double *pval, const char **pp)
 
     d = strtod(p, &tailp);
     if (tailp == p) {
-        monitor_printf(mon, "Number expected\n");
+        monitor_hmp_printf(mon, "Number expected\n");
         return -1;
     }
     if (d != d || d - d != 0) {
         /* NaN or infinity */
-        monitor_printf(mon, "Bad number\n");
+        monitor_hmp_printf(mon, "Bad number\n");
         return -1;
     }
     *pval = d;
@@ -788,7 +778,6 @@ static const HMPCommand *monitor_parse_command(MonitorHMP *hmp,
                                                const char **cmdp,
                                                HMPCommand *table)
 {
-    Monitor *mon = &hmp->parent_obj;
     const char *p;
     const HMPCommand *cmd;
     char cmdname[256];
@@ -801,14 +790,14 @@ static const HMPCommand *monitor_parse_command(MonitorHMP *hmp,
 
     cmd = search_dispatch_table(table, cmdname);
     if (!cmd) {
-        monitor_printf(mon, "unknown command: '%.*s'\n",
-                       (int)(p - cmdp_start), cmdp_start);
+        monitor_hmp_printf(hmp, "unknown command: '%.*s'\n",
+                           (int)(p - cmdp_start), cmdp_start);
         return NULL;
     }
     if (!cmd_available(cmd)) {
-        monitor_printf(mon, "Command '%.*s' not available "
-                            "until machine initialization has completed.\n",
-                       (int)(p - cmdp_start), cmdp_start);
+        monitor_hmp_printf(hmp, "Command '%.*s' not available "
+                           "until machine initialization has completed.\n",
+                           (int)(p - cmdp_start), cmdp_start);
         return NULL;
     }
 
@@ -832,7 +821,7 @@ static const HMPCommand *monitor_parse_command(MonitorHMP *hmp,
  * Else, insert command arguments into a QDict, and return it.
  * Note: On success, caller has to free the QDict structure.
  */
-static QDict *monitor_parse_arguments(Monitor *mon,
+static QDict *monitor_parse_arguments(MonitorHMP *mon,
                                       const char **endp,
                                       const HMPCommand *cmd)
 {
@@ -873,15 +862,15 @@ static QDict *monitor_parse_arguments(Monitor *mon,
                 if (ret < 0) {
                     switch (c) {
                     case 'F':
-                        monitor_printf(mon, "%s: filename expected\n",
-                                       cmd->name);
+                        monitor_hmp_printf(mon, "%s: filename expected\n",
+                                           cmd->name);
                         break;
                     case 'B':
-                        monitor_printf(mon, "%s: block device name expected\n",
-                                       cmd->name);
+                        monitor_hmp_printf(mon, "%s: block device name expected\n",
+                                           cmd->name);
                         break;
                     default:
-                        monitor_printf(mon, "%s: string expected\n", cmd->name);
+                        monitor_hmp_printf(mon, "%s: string expected\n", cmd->name);
                         break;
                     }
                     goto fail;
@@ -968,8 +957,8 @@ static QDict *monitor_parse_arguments(Monitor *mon,
                     }
                 next:
                     if (*p != '\0' && !qemu_isspace(*p)) {
-                        monitor_printf(mon, "invalid char in format: '%c'\n",
-                                       *p);
+                        monitor_hmp_printf(mon, "invalid char in format: '%c'\n",
+                                           *p);
                         goto fail;
                     }
                     if (format < 0) {
@@ -1030,12 +1019,12 @@ static QDict *monitor_parse_arguments(Monitor *mon,
                 }
                 /* Check if 'i' is greater than 32-bit */
                 if ((c == 'i') && ((val >> 32) & 0xffffffff)) {
-                    monitor_printf(mon, "\'%s\' has failed: ", cmd->name);
-                    monitor_printf(mon, "integer is for 32-bit values\n");
+                    monitor_hmp_printf(mon, "\'%s\' has failed: ", cmd->name);
+                    monitor_hmp_printf(mon, "integer is for 32-bit values\n");
                     goto fail;
                 } else if (c == 'M') {
                     if (val < 0) {
-                        monitor_printf(mon, "enter a positive value\n");
+                        monitor_hmp_printf(mon, "enter a positive value\n");
                         goto fail;
                     }
                     val *= MiB;
@@ -1060,7 +1049,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
                 }
                 ret = qemu_strtosz_MiB(p, &end, &val);
                 if (ret < 0 || val > INT64_MAX) {
-                    monitor_printf(mon, "invalid size\n");
+                    monitor_hmp_printf(mon, "invalid size\n");
                     goto fail;
                 }
                 qdict_put_int(qdict, key, val);
@@ -1094,7 +1083,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
                     }
                 }
                 if (*p && !qemu_isspace(*p)) {
-                    monitor_printf(mon, "Unknown unit suffix\n");
+                    monitor_hmp_printf(mon, "Unknown unit suffix\n");
                     goto fail;
                 }
                 qdict_put(qdict, key, qnum_from_double(val));
@@ -1117,7 +1106,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
                 } else if (p - beg == 3 && !memcmp(beg, "off", p - beg)) {
                     val = false;
                 } else {
-                    monitor_printf(mon, "Expected 'on' or 'off'\n");
+                    monitor_hmp_printf(mon, "Expected 'on' or 'off'\n");
                     goto fail;
                 }
                 qdict_put_bool(qdict, key, val);
@@ -1141,8 +1130,8 @@ static QDict *monitor_parse_arguments(Monitor *mon,
                     p++;
                     if (c != *p) {
                         if (!is_valid_option(p, typestr)) {
-                            monitor_printf(mon, "%s: unsupported option -%c\n",
-                                           cmd->name, *p);
+                            monitor_hmp_printf(mon, "%s: unsupported option -%c\n",
+                                               cmd->name, *p);
                             goto fail;
                         } else {
                             skip_key = 1;
@@ -1159,8 +1148,8 @@ static QDict *monitor_parse_arguments(Monitor *mon,
                         }
                         ret = get_str(buf, sizeof(buf), &p);
                         if (ret < 0) {
-                            monitor_printf(mon, "%s: value expected for -%c\n",
-                                           cmd->name, *tmp);
+                            monitor_hmp_printf(mon, "%s: value expected for -%c\n",
+                                               cmd->name, *tmp);
                             goto fail;
                         }
                         qdict_put_str(qdict, key, buf);
@@ -1191,8 +1180,8 @@ static QDict *monitor_parse_arguments(Monitor *mon,
                 }
                 len = strlen(p);
                 if (len <= 0) {
-                    monitor_printf(mon, "%s: string expected\n",
-                                   cmd->name);
+                    monitor_hmp_printf(mon, "%s: string expected\n",
+                                       cmd->name);
                     goto fail;
                 }
                 qdict_put_str(qdict, key, p);
@@ -1201,7 +1190,7 @@ static QDict *monitor_parse_arguments(Monitor *mon,
             break;
         default:
         bad_type:
-            monitor_printf(mon, "%s: unknown type '%c'\n", cmd->name, c);
+            monitor_hmp_printf(mon, "%s: unknown type '%c'\n", cmd->name, c);
             goto fail;
         }
         g_free(key);
@@ -1212,8 +1201,8 @@ static QDict *monitor_parse_arguments(Monitor *mon,
         p++;
     }
     if (*p != '\0') {
-        monitor_printf(mon, "%s: extraneous characters at the end of line\n",
-                       cmd->name);
+        monitor_hmp_printf(mon, "%s: extraneous characters at the end of line\n",
+                           cmd->name);
         goto fail;
     }
 
@@ -1281,19 +1270,19 @@ void handle_hmp_command(MonitorHMP *hmp, const char *cmdline)
 
     if (!cmd->cmd && !cmd->cmd_info_hrt) {
         /* FIXME: is it useful to try autoload modules here ??? */
-        monitor_printf(&hmp->parent_obj, "Command \"%.*s\" is not available.\n",
-                       (int)(cmdline - cmd_start), cmd_start);
+        monitor_hmp_printf(hmp, "Command \"%.*s\" is not available.\n",
+                           (int)(cmdline - cmd_start), cmd_start);
         return;
     }
 
-    qdict = monitor_parse_arguments(&hmp->parent_obj, &cmdline, cmd);
+    qdict = monitor_parse_arguments(hmp, &cmdline, cmd);
     if (!qdict) {
         while (cmdline > cmd_start && qemu_isspace(cmdline[-1])) {
             cmdline--;
         }
-        monitor_printf(&hmp->parent_obj,
-                       "Try \"help %.*s\" for more information\n",
-                       (int)(cmdline - cmd_start), cmd_start);
+        monitor_hmp_printf(hmp,
+                           "Try \"help %.*s\" for more information\n",
+                           (int)(cmdline - cmd_start), cmd_start);
         return;
     }
 
@@ -1539,7 +1528,7 @@ static void monitor_read(void *opaque, const uint8_t *buf, int size)
         }
     } else {
         if (size == 0 || buf[size - 1] != 0) {
-            monitor_printf(&hmp->parent_obj, "corrupted command\n");
+            monitor_hmp_printf(hmp, "corrupted command\n");
         } else {
             handle_hmp_command(hmp, (char *)buf);
         }
@@ -1580,8 +1569,8 @@ static void monitor_event(void *opaque, QEMUChrEvent event)
         break;
 
     case CHR_EVENT_OPENED:
-        monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
-                       "information\n", QEMU_VERSION);
+        monitor_hmp_printf(hmp, "QEMU %s monitor - type 'help' for more "
+                           "information\n", QEMU_VERSION);
         qemu_mutex_lock(&mon->mon_lock);
         hmp->reset_seen = 1;
         if (!mon->mux_out && hmp->use_readline) {
@@ -1613,7 +1602,7 @@ static void G_GNUC_PRINTF(2, 3) monitor_readline_printf(void *opaque,
     MonitorHMP *hmp = opaque;
     va_list ap;
     va_start(ap, fmt);
-    monitor_vprintf(&hmp->parent_obj, fmt, ap);
+    monitor_hmp_vprintf(hmp, fmt, ap);
     va_end(ap);
 }
 
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index afdda1386080..c198c12eaa00 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -108,12 +108,6 @@ typedef struct HMPCommand {
 struct MonitorClass {
     ObjectClass parent_class;
 
-    /*
-     * If non-NULL, the monitor is able to print messages
-     * for attention of the client user
-     */
-    int (*vprintf)(Monitor *mon, const char *fmt, va_list ap)
-        G_GNUC_PRINTF(2, 0);
     /*
      * If non-NULL, the monitor is able to send event
      * notifications back to the client
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 8528af6f79b8..da76e6e4ac19 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -272,58 +272,53 @@ int monitor_puts(Monitor *mon, const char *str)
     return monitor_puts_locked(mon, str);
 }
 
-int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
+int monitor_hmp_vprintf(MonitorHMP *mon, const char *fmt, va_list ap)
 {
-    MonitorClass *moncls;
+    g_autofree char *buf = g_strdup_vprintf(fmt, ap);
 
     if (!mon) {
         return -1;
     }
 
-    moncls = MONITOR_GET_CLASS(mon);
-    if (!moncls->vprintf) {
-        return -1;
-    }
-
-    return moncls->vprintf(mon, fmt, ap);
+    return monitor_puts(MONITOR(mon), buf);
 }
 
-int monitor_printf(Monitor *mon, const char *fmt, ...)
+int monitor_hmp_printf(MonitorHMP *mon, const char *fmt, ...)
 {
     int ret;
 
     va_list ap;
     va_start(ap, fmt);
-    ret = monitor_vprintf(mon, fmt, ap);
+    ret = monitor_hmp_vprintf(mon, fmt, ap);
     va_end(ap);
     return ret;
 }
 
-void monitor_printc(Monitor *mon, int c)
+void monitor_hmp_printc(MonitorHMP *mon, int c)
 {
-    monitor_printf(mon, "'");
+    monitor_hmp_printf(mon, "'");
     switch(c) {
     case '\'':
-        monitor_printf(mon, "\\'");
+        monitor_hmp_printf(mon, "\\'");
         break;
     case '\\':
-        monitor_printf(mon, "\\\\");
+        monitor_hmp_printf(mon, "\\\\");
         break;
     case '\n':
-        monitor_printf(mon, "\\n");
+        monitor_hmp_printf(mon, "\\n");
         break;
     case '\r':
-        monitor_printf(mon, "\\r");
+        monitor_hmp_printf(mon, "\\r");
         break;
     default:
         if (c >= 32 && c <= 126) {
-            monitor_printf(mon, "%c", c);
+            monitor_hmp_printf(mon, "%c", c);
         } else {
-            monitor_printf(mon, "\\x%02x", c);
+            monitor_hmp_printf(mon, "\\x%02x", c);
         }
         break;
     }
-    monitor_printf(mon, "'");
+    monitor_hmp_printf(mon, "'");
 }
 
 static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
diff --git a/net/net-hmp-cmds.c b/net/net-hmp-cmds.c
index 5b1c678f5d89..0d718d78aef9 100644
--- a/net/net-hmp-cmds.c
+++ b/net/net-hmp-cmds.c
@@ -28,26 +28,25 @@
 #include "qemu/help_option.h"
 #include "qemu/option.h"
 
-static void hmp_print_client_info(Monitor *mon, NetworkClientInfo *ci)
+static void hmp_print_client_info(MonitorHMP *hmp, NetworkClientInfo *ci)
 {
     NetFilterInfoList *f;
 
-    monitor_printf(mon, "%s: index=%" PRIu32 ",type=%s,%s\n",
-                   ci->name, ci->queue_index,
-                   NetClientDriver_str(ci->type), ci->info_str);
+    monitor_hmp_printf(hmp, "%s: index=%" PRIu32 ",type=%s,%s\n",
+                       ci->name, ci->queue_index,
+                       NetClientDriver_str(ci->type), ci->info_str);
     if (ci->filters) {
-        monitor_printf(mon, "filters:\n");
+        monitor_hmp_printf(hmp, "filters:\n");
         for (f = ci->filters; f; f = f->next) {
-            monitor_printf(mon, "  - %s: type=%s%s%s\n",
-                           f->value->name, f->value->type,
-                           f->value->info[0] ? "," : "", f->value->info);
+            monitor_hmp_printf(hmp, "  - %s: type=%s%s%s\n",
+                               f->value->name, f->value->type,
+                               f->value->info[0] ? "," : "", f->value->info);
         }
     }
 }
 
 void hmp_info_network(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     Error *err = NULL;
     g_autoptr(NetworkInfo) info = qmp_x_query_network(&err);
     NetHubInfoList *h;
@@ -60,13 +59,13 @@ void hmp_info_network(MonitorHMP *hmp, const QDict *qdict)
     for (h = info->hubs; h; h = h->next) {
         NetHubPortInfoList *p;
 
-        monitor_printf(mon, "hub %d\n", (int)h->value->id);
+        monitor_hmp_printf(hmp, "hub %d\n", (int)h->value->id);
         for (p = h->value->ports; p; p = p->next) {
             if (p->value->peer) {
-                monitor_printf(mon, " \\ %s: ", p->value->name);
-                hmp_print_client_info(mon, p->value->peer);
+                monitor_hmp_printf(hmp, " \\ %s: ", p->value->name);
+                hmp_print_client_info(hmp, p->value->peer);
             } else {
-                monitor_printf(mon, " \\ %s\n", p->value->name);
+                monitor_hmp_printf(hmp, " \\ %s\n", p->value->name);
             }
         }
     }
@@ -75,11 +74,11 @@ void hmp_info_network(MonitorHMP *hmp, const QDict *qdict)
         NetworkClientInfo *ci = entry->value;
 
         if (!ci->peer || ci->type == NET_CLIENT_DRIVER_NIC) {
-            hmp_print_client_info(mon, ci);
+            hmp_print_client_info(hmp, ci);
         } /* else it's a netdev connected to a NIC, printed with the NIC */
         if (ci->peer && ci->type == NET_CLIENT_DRIVER_NIC) {
-            monitor_printf(mon, " \\ ");
-            hmp_print_client_info(mon, ci->peer);
+            monitor_hmp_printf(hmp, " \\ ");
+            hmp_print_client_info(hmp, ci->peer);
         }
     }
 }
diff --git a/net/slirp.c b/net/slirp.c
index d5c190b48b76..6fbefa9ed1d7 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -711,22 +711,22 @@ error:
     return -1;
 }
 
-static SlirpState *slirp_lookup(Monitor *mon, const char *id)
+static SlirpState *slirp_lookup(MonitorHMP *hmp, const char *id)
 {
     if (id) {
         NetClientState *nc = qemu_find_netdev(id);
         if (!nc) {
-            monitor_printf(mon, "unrecognized netdev id '%s'\n", id);
+            monitor_hmp_printf(hmp, "unrecognized netdev id '%s'\n", id);
             return NULL;
         }
         if (strcmp(nc->model, "user")) {
-            monitor_printf(mon, "invalid device specified\n");
+            monitor_hmp_printf(hmp, "invalid device specified\n");
             return NULL;
         }
         return DO_UPCAST(SlirpState, nc, nc);
     } else {
         if (QTAILQ_EMPTY(&slirp_stacks)) {
-            monitor_printf(mon, "user mode network stack not in use\n");
+            monitor_hmp_printf(hmp, "user mode network stack not in use\n");
             return NULL;
         }
         return QTAILQ_FIRST(&slirp_stacks);
@@ -735,7 +735,6 @@ static SlirpState *slirp_lookup(Monitor *mon, const char *id)
 
 void hmp_hostfwd_remove(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     /* TODO: support removing unix fwd */
     struct sockaddr_in host_addr = {
         .sin_family = AF_INET,
@@ -753,10 +752,10 @@ void hmp_hostfwd_remove(MonitorHMP *hmp, const QDict *qdict)
     const char *arg2 = qdict_get_try_str(qdict, "arg2");
 
     if (arg2) {
-        s = slirp_lookup(mon, arg1);
+        s = slirp_lookup(hmp, arg1);
         src_str = arg2;
     } else {
-        s = slirp_lookup(mon, NULL);
+        s = slirp_lookup(hmp, NULL);
         src_str = arg1;
     }
     if (!s) {
@@ -795,12 +794,12 @@ void hmp_hostfwd_remove(MonitorHMP *hmp, const QDict *qdict)
     err = slirp_remove_hostfwd(s->slirp, is_udp, host_addr.sin_addr, host_port);
 #endif
 
-    monitor_printf(mon, "host forwarding rule for %s %s\n", src_str,
-                   err ? "not found" : "removed");
+    monitor_hmp_printf(hmp, "host forwarding rule for %s %s\n", src_str,
+                       err ? "not found" : "removed");
     return;
 
  fail_syntax:
-    monitor_printf(mon, "invalid format\n");
+    monitor_hmp_printf(hmp, "invalid format\n");
 }
 
 static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
@@ -960,17 +959,16 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
 
 void hmp_hostfwd_add(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *redir_str;
     SlirpState *s;
     const char *arg1 = qdict_get_str(qdict, "arg1");
     const char *arg2 = qdict_get_try_str(qdict, "arg2");
 
     if (arg2) {
-        s = slirp_lookup(mon, arg1);
+        s = slirp_lookup(hmp, arg1);
         redir_str = arg2;
     } else {
-        s = slirp_lookup(mon, NULL);
+        s = slirp_lookup(hmp, NULL);
         redir_str = arg1;
     }
     if (s) {
@@ -1228,16 +1226,15 @@ UsernetInfoList *qmp_x_query_usernet(Error **errp)
 
 void hmp_info_usernet(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     g_autoptr(UsernetInfoList) list = NULL;
     UsernetInfoList *entry;
 
     list = qmp_x_query_usernet(&error_abort);
     for (entry = list; entry; entry = entry->next) {
         UsernetInfo *ui = entry->value;
-        monitor_printf(mon, "Hub %d (%s):\n%s",
-                       ui->has_hub_id ? (int)ui->hub_id : -1,
-                       ui->hub_name, ui->info);
+        monitor_hmp_printf(hmp, "Hub %d (%s):\n%s",
+                           ui->has_hub_id ? (int)ui->hub_id : -1,
+                           ui->hub_name, ui->info);
     }
 }
 
diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c
index 2e2eb33371e2..bbf5980332a4 100644
--- a/qom/qom-hmp-cmds.c
+++ b/qom/qom-hmp-cmds.c
@@ -20,13 +20,12 @@
 
 void hmp_qom_list(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *path = qdict_get_try_str(qdict, "path");
     ObjectPropertyInfoList *list;
     Error *err = NULL;
 
     if (path == NULL) {
-        monitor_printf(mon, "/\n");
+        monitor_hmp_printf(hmp, "/\n");
         return;
     }
 
@@ -36,8 +35,8 @@ void hmp_qom_list(MonitorHMP *hmp, const QDict *qdict)
         while (list != NULL) {
             ObjectPropertyInfo *value = list->value;
 
-            monitor_printf(mon, "%s (%s)\n",
-                           value->name, value->type);
+            monitor_hmp_printf(hmp, "%s (%s)\n",
+                               value->name, value->type);
             list = list->next;
         }
         qapi_free_ObjectPropertyInfoList(start);
@@ -75,7 +74,6 @@ void hmp_qom_set(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_qom_get(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *path = qdict_get_str(qdict, "path");
     const char *property = qdict_get_str(qdict, "property");
     Error *err = NULL;
@@ -83,7 +81,7 @@ void hmp_qom_get(MonitorHMP *hmp, const QDict *qdict)
 
     if (err == NULL) {
         GString *str = qobject_to_json_pretty(obj, true);
-        monitor_printf(mon, "%s\n", str->str);
+        monitor_hmp_printf(hmp, "%s\n", str->str);
         g_string_free(str, true);
     }
 
@@ -96,7 +94,7 @@ typedef struct QOMCompositionState {
     int indent;
 } QOMCompositionState;
 
-static void print_qom_composition(Monitor *mon, Object *obj, int indent);
+static void print_qom_composition(MonitorHMP *hmp, Object *obj, int indent);
 
 static int qom_composition_compare(const void *a, const void *b)
 {
@@ -110,7 +108,7 @@ static int insert_qom_composition_child(Object *obj, void *opaque)
     return 0;
 }
 
-static void print_qom_composition(Monitor *mon, Object *obj, int indent)
+static void print_qom_composition(MonitorHMP *hmp, Object *obj, int indent)
 {
     GArray *children = g_array_new(false, false, sizeof(Object *));
     const char *name;
@@ -121,14 +119,14 @@ static void print_qom_composition(Monitor *mon, Object *obj, int indent)
     } else {
         name = object_get_canonical_path_component(obj);
     }
-    monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name,
-                   object_get_typename(obj));
+    monitor_hmp_printf(hmp, "%*s/%s (%s)\n", indent, "", name,
+                       object_get_typename(obj));
 
     object_child_foreach(obj, insert_qom_composition_child, children);
     g_array_sort(children, qom_composition_compare);
 
     for (i = 0; i < children->len; i++) {
-        print_qom_composition(mon, g_array_index(children, Object *, i),
+        print_qom_composition(hmp, g_array_index(children, Object *, i),
                               indent + 2);
     }
     g_array_free(children, TRUE);
@@ -136,7 +134,6 @@ static void print_qom_composition(Monitor *mon, Object *obj, int indent)
 
 void hmp_info_qom_tree(MonitorHMP *hmp, const QDict *dict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *path = qdict_get_try_str(dict, "path");
     Object *obj;
     bool ambiguous = false;
@@ -144,17 +141,17 @@ void hmp_info_qom_tree(MonitorHMP *hmp, const QDict *dict)
     if (path) {
         obj = object_resolve_path(path, &ambiguous);
         if (!obj) {
-            monitor_printf(mon, "Path '%s' could not be resolved.\n", path);
+            monitor_hmp_printf(hmp, "Path '%s' could not be resolved.\n", path);
             return;
         }
         if (ambiguous) {
-            monitor_printf(mon, "Warning: Path '%s' is ambiguous.\n", path);
+            monitor_hmp_printf(hmp, "Warning: Path '%s' is ambiguous.\n", path);
             return;
         }
     } else {
         obj = qdev_get_machine();
     }
-    print_qom_composition(mon, obj, 0);
+    print_qom_composition(hmp, obj, 0);
 }
 
 void hmp_object_add(MonitorHMP *hmp, const QDict *qdict)
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
index ef69d23ff507..965565715ef2 100644
--- a/replay/replay-debugging.c
+++ b/replay/replay-debugging.c
@@ -33,11 +33,10 @@ bool replay_running_debug(void)
 
 void hmp_info_replay(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     if (replay_mode == REPLAY_MODE_NONE) {
-        monitor_printf(mon, "Record/replay is not active\n");
+        monitor_hmp_printf(hmp, "Record/replay is not active\n");
     } else {
-        monitor_printf(mon,
+        monitor_hmp_printf(hmp,
             "%s execution '%s': instruction count = %"PRId64"\n",
             replay_mode == REPLAY_MODE_RECORD ? "Recording" : "Replaying",
             replay_get_filename(), replay_get_current_icount());
diff --git a/stats/stats-hmp-cmds.c b/stats/stats-hmp-cmds.c
index cd1f1deb58bc..3d556c745d61 100644
--- a/stats/stats-hmp-cmds.c
+++ b/stats/stats-hmp-cmds.c
@@ -14,11 +14,11 @@
 #include "qobject/qdict.h"
 #include "qapi/error.h"
 
-static void print_stats_schema_value(Monitor *mon, StatsSchemaValue *value)
+static void print_stats_schema_value(MonitorHMP *hmp, StatsSchemaValue *value)
 {
     const char *unit = NULL;
-    monitor_printf(mon, "    %s (%s%s", value->name, StatsType_str(value->type),
-                   value->has_unit || value->exponent ? ", " : "");
+    monitor_hmp_printf(hmp, "    %s (%s%s", value->name, StatsType_str(value->type),
+                       value->has_unit || value->exponent ? ", " : "");
 
     if (value->has_unit) {
         if (value->unit == STATS_UNIT_SECONDS) {
@@ -31,29 +31,29 @@ static void print_stats_schema_value(Monitor *mon, StatsSchemaValue *value)
     if (unit && value->base == 10 &&
         value->exponent >= -18 && value->exponent <= 18 &&
         value->exponent % 3 == 0) {
-        monitor_puts(mon, si_prefix(value->exponent));
+        monitor_puts(MONITOR(hmp), si_prefix(value->exponent));
     } else if (unit && value->base == 2 &&
                value->exponent >= 0 && value->exponent <= 60 &&
                value->exponent % 10 == 0) {
 
-        monitor_puts(mon, iec_binary_prefix(value->exponent));
+        monitor_puts(MONITOR(hmp), iec_binary_prefix(value->exponent));
     } else if (value->exponent) {
         /* Use exponential notation and write the unit's English name */
-        monitor_printf(mon, "* %d^%d%s",
-                       value->base, value->exponent,
-                       value->has_unit ? " " : "");
+        monitor_hmp_printf(hmp, "* %d^%d%s",
+                           value->base, value->exponent,
+                           value->has_unit ? " " : "");
         unit = NULL;
     }
 
     if (value->has_unit) {
-        monitor_puts(mon, unit ? unit : StatsUnit_str(value->unit));
+        monitor_puts(MONITOR(hmp), unit ? unit : StatsUnit_str(value->unit));
     }
 
     /* Print bucket size for linear histograms */
     if (value->type == STATS_TYPE_LINEAR_HISTOGRAM && value->has_bucket_size) {
-        monitor_printf(mon, ", bucket size=%d", value->bucket_size);
+        monitor_hmp_printf(hmp, ", bucket size=%d", value->bucket_size);
     }
-    monitor_printf(mon, ")");
+    monitor_hmp_printf(hmp, ")");
 }
 
 static StatsSchemaValueList *find_schema_value_list(
@@ -71,7 +71,7 @@ static StatsSchemaValueList *find_schema_value_list(
     return NULL;
 }
 
-static void print_stats_results(Monitor *mon, StatsTarget target,
+static void print_stats_results(MonitorHMP *hmp, StatsTarget target,
                                 bool show_provider,
                                 StatsResult *result,
                                 StatsSchemaList *schema)
@@ -82,14 +82,14 @@ static void print_stats_results(Monitor *mon, StatsTarget target,
     StatsList *stats_list;
 
     if (!schema_value_list) {
-        monitor_printf(mon, "failed to find schema list for %s\n",
-                       StatsProvider_str(result->provider));
+        monitor_hmp_printf(hmp, "failed to find schema list for %s\n",
+                           StatsProvider_str(result->provider));
         return;
     }
 
     if (show_provider) {
-        monitor_printf(mon, "provider: %s\n",
-                       StatsProvider_str(result->provider));
+        monitor_hmp_printf(hmp, "provider: %s\n",
+                           StatsProvider_str(result->provider));
     }
 
     for (stats_list = result->stats; stats_list;
@@ -103,31 +103,31 @@ static void print_stats_results(Monitor *mon, StatsTarget target,
         /* Find schema entry */
         while (!g_str_equal(stats->name, schema_value->name)) {
             if (!schema_value_list->next) {
-                monitor_printf(mon, "failed to find schema entry for %s\n",
-                               stats->name);
+                monitor_hmp_printf(hmp, "failed to find schema entry for %s\n",
+                                   stats->name);
                 return;
             }
             schema_value_list = schema_value_list->next;
             schema_value = schema_value_list->value;
         }
 
-        print_stats_schema_value(mon, schema_value);
+        print_stats_schema_value(hmp, schema_value);
 
         if (stats_value->type == QTYPE_QNUM) {
-            monitor_printf(mon, ": %" PRId64 "\n", stats_value->u.scalar);
+            monitor_hmp_printf(hmp, ": %" PRId64 "\n", stats_value->u.scalar);
         } else if (stats_value->type == QTYPE_QBOOL) {
-            monitor_printf(mon, ": %s\n", stats_value->u.boolean ? "yes" : "no");
+            monitor_hmp_printf(hmp, ": %s\n", stats_value->u.boolean ? "yes" : "no");
         } else if (stats_value->type == QTYPE_QLIST) {
             uint64List *list;
             int i;
 
-            monitor_printf(mon, ": ");
+            monitor_hmp_printf(hmp, ": ");
             for (list = stats_value->u.list, i = 1;
                  list;
                  list = list->next, i++) {
-                monitor_printf(mon, "[%d]=%" PRId64 " ", i, list->value);
+                monitor_hmp_printf(hmp, "[%d]=%" PRId64 " ", i, list->value);
             }
-            monitor_printf(mon, "\n");
+            monitor_hmp_printf(hmp, "\n");
         }
     }
 }
@@ -189,7 +189,6 @@ static StatsFilter *stats_filter(StatsTarget target, const char *names,
 
 void hmp_info_stats(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *target_str = qdict_get_str(qdict, "target");
     const char *provider_str = qdict_get_try_str(qdict, "provider");
     const char *names = qdict_get_try_str(qdict, "names");
@@ -204,13 +203,13 @@ void hmp_info_stats(MonitorHMP *hmp, const QDict *qdict)
 
     target = qapi_enum_parse(&StatsTarget_lookup, target_str, -1, &err);
     if (err) {
-        monitor_printf(mon, "invalid stats target %s\n", target_str);
+        monitor_hmp_printf(hmp, "invalid stats target %s\n", target_str);
         goto exit_no_print;
     }
     if (provider_str) {
         provider = qapi_enum_parse(&StatsProvider_lookup, provider_str, -1, &err);
         if (err) {
-            monitor_printf(mon, "invalid stats provider %s\n", provider_str);
+            monitor_hmp_printf(hmp, "invalid stats provider %s\n", provider_str);
             goto exit_no_print;
         }
     }
@@ -241,12 +240,12 @@ void hmp_info_stats(MonitorHMP *hmp, const QDict *qdict)
         goto exit;
     }
     for (entry = stats; entry; entry = entry->next) {
-        print_stats_results(mon, target, provider_str == NULL, entry->value, schema);
+        print_stats_results(hmp, target, provider_str == NULL, entry->value, schema);
     }
 
 exit:
     if (err) {
-        monitor_printf(mon, "%s\n", error_get_pretty(err));
+        monitor_hmp_printf(hmp, "%s\n", error_get_pretty(err));
     }
 exit_no_print:
     error_free(err);
diff --git a/stubs/hmp-cmd-info_sev.c b/stubs/hmp-cmd-info_sev.c
index 6f2b87d1ad10..c9c1d10c165c 100644
--- a/stubs/hmp-cmd-info_sev.c
+++ b/stubs/hmp-cmd-info_sev.c
@@ -12,6 +12,5 @@
 
 void hmp_info_sev(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
-    monitor_printf(mon, "SEV is not available in this QEMU\n");
+    monitor_hmp_printf(hmp, "SEV is not available in this QEMU\n");
 }
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
index b0c7002bd406..094b80721003 100644
--- a/stubs/monitor-core.c
+++ b/stubs/monitor-core.c
@@ -17,7 +17,7 @@ void qapi_event_emit(QAPIEvent event, QDict *qdict)
 {
 }
 
-int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
+int monitor_hmp_vprintf(MonitorHMP *mon, const char *fmt, va_list ap)
 {
     /*
      * Pretend 'g_test_message' is our monitor console to
diff --git a/system/dirtylimit-hmp-cmds.c b/system/dirtylimit-hmp-cmds.c
index 75194add7931..fb9338e9aef6 100644
--- a/system/dirtylimit-hmp-cmds.c
+++ b/system/dirtylimit-hmp-cmds.c
@@ -17,7 +17,6 @@
 
 void hmp_cancel_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     int64_t cpu_index = qdict_get_try_int(qdict, "cpu_index", -1);
     Error *err = NULL;
 
@@ -27,8 +26,8 @@ void hmp_cancel_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 
-    monitor_printf(mon, "[Please use 'info vcpu_dirty_limit' to query "
-                   "dirty limit for virtual CPU]\n");
+    monitor_hmp_printf(hmp, "[Please use 'info vcpu_dirty_limit' to query "
+                       "dirty limit for virtual CPU]\n");
 }
 
 void hmp_set_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
@@ -50,13 +49,12 @@ out:
 
 void hmp_info_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     DirtyLimitInfoList *info;
     g_autoptr(DirtyLimitInfoList) head = NULL;
     Error *err = NULL;
 
     if (!dirtylimit_in_service()) {
-        monitor_printf(mon, "Dirty page limit not enabled!\n");
+        monitor_hmp_printf(hmp, "Dirty page limit not enabled!\n");
         return;
     }
 
@@ -67,7 +65,7 @@ void hmp_info_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
     }
 
     for (info = head; info != NULL; info = info->next) {
-        monitor_printf(mon, "vcpu[%"PRIi64"], limit rate %"PRIi64 " (MB/s),"
+        monitor_hmp_printf(hmp, "vcpu[%"PRIi64"], limit rate %"PRIi64 " (MB/s),"
                             " current rate %"PRIi64 " (MB/s)\n",
                             info->value->cpu_index,
                             info->value->limit_rate,
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index 5c2de2f53cc9..3860ada2a237 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -763,9 +763,10 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
     return ret;
 }
 
-#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
+#define qdev_printf(fmt, ...) \
+    monitor_hmp_printf(hmp, "%*s" fmt, indent, "", ## __VA_ARGS__)
 
-static void qdev_print_props(Monitor *mon, DeviceState *dev, DeviceClass *dc,
+static void qdev_print_props(MonitorHMP *hmp, DeviceState *dev, DeviceClass *dc,
                              int indent)
 {
     for (int i = 0, n = dc->props_count_; i < n; ++i) {
@@ -798,8 +799,9 @@ static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int ind
     }
 }
 
-static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
+static void qdev_print(MonitorHMP *hmp, DeviceState *dev, int indent)
 {
+    Monitor *mon = MONITOR(hmp);
     ObjectClass *class;
     NamedGPIOList *ngl;
     NamedClockList *ncl;
@@ -823,13 +825,13 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
     }
     class = object_get_class(OBJECT(dev));
     do {
-        qdev_print_props(mon, dev, DEVICE_CLASS(class), indent);
+        qdev_print_props(hmp, dev, DEVICE_CLASS(class), indent);
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
     bus_print_dev(dev->parent_bus, mon, dev, indent);
 }
 
-static void qbus_print(Monitor *mon, BusState *bus, int indent, bool details)
+static void qbus_print(MonitorHMP *hmp, BusState *bus, int indent, bool details)
 {
     BusChild *kid;
 
@@ -842,10 +844,10 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent, bool details)
         qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
                     dev->id ? dev->id : "");
         if (details) {
-            qdev_print(mon, dev, indent + 2);
+            qdev_print(hmp, dev, indent + 2);
         }
         QLIST_FOREACH(child_bus, &dev->child_bus, sibling) {
-            qbus_print(mon, child_bus, indent + 2, details);
+            qbus_print(hmp, child_bus, indent + 2, details);
         }
     }
 }
@@ -853,11 +855,10 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent, bool details)
 
 void hmp_info_qtree(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     bool details = !qdict_get_try_bool(qdict, "brief", false);
 
     if (sysbus_get_default()) {
-        qbus_print(mon, sysbus_get_default(), 0, details);
+        qbus_print(hmp, sysbus_get_default(), 0, details);
     }
 }
 
diff --git a/system/runstate-hmp-cmds.c b/system/runstate-hmp-cmds.c
index 051ee45ee74c..ad70b53f8abf 100644
--- a/system/runstate-hmp-cmds.c
+++ b/system/runstate-hmp-cmds.c
@@ -25,33 +25,31 @@
 
 void hmp_info_status(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     StatusInfo *info;
 
     info = qmp_query_status(NULL);
 
-    monitor_printf(mon, "VM status: %s",
-                   info->running ? "running" : "paused");
+    monitor_hmp_printf(hmp, "VM status: %s",
+                       info->running ? "running" : "paused");
 
     if (!info->running && info->status != RUN_STATE_PAUSED) {
-        monitor_printf(mon, " (%s)", RunState_str(info->status));
+        monitor_hmp_printf(hmp, " (%s)", RunState_str(info->status));
     }
 
-    monitor_printf(mon, "\n");
+    monitor_hmp_printf(hmp, "\n");
 
     qapi_free_StatusInfo(info);
 }
 
 void hmp_one_insn_per_tb(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *option = qdict_get_try_str(qdict, "option");
     AccelState *accel = current_accel();
     bool newval;
 
     if (!object_property_find(OBJECT(accel), "one-insn-per-tb")) {
-        monitor_printf(mon,
-                       "This accelerator does not support setting one-insn-per-tb\n");
+        monitor_hmp_printf(hmp,
+                           "This accelerator does not support setting one-insn-per-tb\n");
         return;
     }
 
@@ -60,7 +58,7 @@ void hmp_one_insn_per_tb(MonitorHMP *hmp, const QDict *qdict)
     } else if (!strcmp(option, "off")) {
         newval = false;
     } else {
-        monitor_printf(mon, "unexpected option %s\n", option);
+        monitor_hmp_printf(hmp, "unexpected option %s\n", option);
         return;
     }
     /* If the property exists then setting it can never fail */
diff --git a/system/tpm-hmp-cmds.c b/system/tpm-hmp-cmds.c
index 094c3f16cf50..35406e24d2c3 100644
--- a/system/tpm-hmp-cmds.c
+++ b/system/tpm-hmp-cmds.c
@@ -13,7 +13,6 @@
 
 void hmp_info_tpm(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
 #ifdef CONFIG_TPM
     TPMInfoList *info_list, *info;
     Error *err = NULL;
@@ -23,44 +22,44 @@ void hmp_info_tpm(MonitorHMP *hmp, const QDict *qdict)
 
     info_list = qmp_query_tpm(&err);
     if (err) {
-        monitor_printf(mon, "TPM device not supported\n");
+        monitor_hmp_printf(hmp, "TPM device not supported\n");
         error_free(err);
         return;
     }
 
     if (info_list) {
-        monitor_printf(mon, "TPM device:\n");
+        monitor_hmp_printf(hmp, "TPM device:\n");
     }
 
     for (info = info_list; info; info = info->next) {
         TPMInfo *ti = info->value;
-        monitor_printf(mon, " tpm%d: model=%s\n",
-                       c, TpmModel_str(ti->model));
+        monitor_hmp_printf(hmp, " tpm%d: model=%s\n",
+                           c, TpmModel_str(ti->model));
 
-        monitor_printf(mon, "  \\ %s: type=%s",
-                       ti->id, TpmType_str(ti->options->type));
+        monitor_hmp_printf(hmp, "  \\ %s: type=%s",
+                           ti->id, TpmType_str(ti->options->type));
 
         switch (ti->options->type) {
         case TPM_TYPE_PASSTHROUGH:
             tpo = ti->options->u.passthrough.data;
-            monitor_printf(mon, "%s%s%s%s",
-                           tpo->path ? ",path=" : "",
-                           tpo->path ?: "",
-                           tpo->cancel_path ? ",cancel-path=" : "",
-                           tpo->cancel_path ?: "");
+            monitor_hmp_printf(hmp, "%s%s%s%s",
+                               tpo->path ? ",path=" : "",
+                               tpo->path ?: "",
+                               tpo->cancel_path ? ",cancel-path=" : "",
+                               tpo->cancel_path ?: "");
             break;
         case TPM_TYPE_EMULATOR:
             teo = ti->options->u.emulator.data;
-            monitor_printf(mon, ",chardev=%s", teo->chardev);
+            monitor_hmp_printf(hmp, ",chardev=%s", teo->chardev);
             break;
         case TPM_TYPE__MAX:
             break;
         }
-        monitor_printf(mon, "\n");
+        monitor_hmp_printf(hmp, "\n");
         c++;
     }
     qapi_free_TPMInfoList(info_list);
 #else
-    monitor_printf(mon, "TPM device not supported\n");
+    monitor_hmp_printf(hmp, "TPM device not supported\n");
 #endif /* CONFIG_TPM */
 }
diff --git a/target/i386/cpu-apic.c b/target/i386/cpu-apic.c
index 3ae20f004b64..5d69ece15034 100644
--- a/target/i386/cpu-apic.c
+++ b/target/i386/cpu-apic.c
@@ -82,7 +82,6 @@ void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
 
 void hmp_info_local_apic(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     CPUState *cs;
 
     if (qdict_haskey(qdict, "apic-id")) {
@@ -98,7 +97,7 @@ void hmp_info_local_apic(MonitorHMP *hmp, const QDict *qdict)
 
 
     if (!cs) {
-        monitor_printf(mon, "No CPU available\n");
+        monitor_hmp_printf(hmp, "No CPU available\n");
         return;
     }
     x86_cpu_dump_local_apic_state(cs, CPU_DUMP_FPU);
diff --git a/target/i386/monitor.c b/target/i386/monitor.c
index 72bcab131f77..46762540ba65 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -48,27 +48,27 @@ static hwaddr addr_canonical(CPUArchState *env, hwaddr addr)
     return addr;
 }
 
-static void print_pte(Monitor *mon, CPUArchState *env, hwaddr addr,
+static void print_pte(MonitorHMP *hmp, CPUArchState *env, hwaddr addr,
                       hwaddr pte, hwaddr mask)
 {
     addr = addr_canonical(env, addr);
 
-    monitor_printf(mon, HWADDR_FMT_plx ": " HWADDR_FMT_plx
-                   " %c%c%c%c%c%c%c%c%c\n",
-                   addr,
-                   pte & mask,
-                   pte & PG_NX_MASK ? 'X' : '-',
-                   pte & PG_GLOBAL_MASK ? 'G' : '-',
-                   pte & PG_PSE_MASK ? 'P' : '-',
-                   pte & PG_DIRTY_MASK ? 'D' : '-',
-                   pte & PG_ACCESSED_MASK ? 'A' : '-',
-                   pte & PG_PCD_MASK ? 'C' : '-',
-                   pte & PG_PWT_MASK ? 'T' : '-',
-                   pte & PG_USER_MASK ? 'U' : '-',
-                   pte & PG_RW_MASK ? 'W' : '-');
+    monitor_hmp_printf(hmp, HWADDR_FMT_plx ": " HWADDR_FMT_plx
+                       " %c%c%c%c%c%c%c%c%c\n",
+                       addr,
+                       pte & mask,
+                       pte & PG_NX_MASK ? 'X' : '-',
+                       pte & PG_GLOBAL_MASK ? 'G' : '-',
+                       pte & PG_PSE_MASK ? 'P' : '-',
+                       pte & PG_DIRTY_MASK ? 'D' : '-',
+                       pte & PG_ACCESSED_MASK ? 'A' : '-',
+                       pte & PG_PCD_MASK ? 'C' : '-',
+                       pte & PG_PWT_MASK ? 'T' : '-',
+                       pte & PG_USER_MASK ? 'U' : '-',
+                       pte & PG_RW_MASK ? 'W' : '-');
 }
 
-static void tlb_info_32(Monitor *mon, CPUArchState *env, AddressSpace *as)
+static void tlb_info_32(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
 {
     const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
     unsigned int l1, l2;
@@ -80,13 +80,13 @@ static void tlb_info_32(Monitor *mon, CPUArchState *env, AddressSpace *as)
         if (pde & PG_PRESENT_MASK) {
             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
                 /* 4M pages */
-                print_pte(mon, env, (l1 << 22), pde, ~((1 << 21) - 1));
+                print_pte(hmp, env, (l1 << 22), pde, ~((1 << 21) - 1));
             } else {
                 for(l2 = 0; l2 < 1024; l2++) {
                     pte = address_space_ldl_le(as, (pde & ~0xfff) + l2 * 4,
                                                attrs, NULL);
                     if (pte & PG_PRESENT_MASK) {
-                        print_pte(mon, env, (l1 << 22) + (l2 << 12),
+                        print_pte(hmp, env, (l1 << 22) + (l2 << 12),
                                   pte & ~PG_PSE_MASK,
                                   ~0xfff);
                     }
@@ -96,7 +96,7 @@ static void tlb_info_32(Monitor *mon, CPUArchState *env, AddressSpace *as)
     }
 }
 
-static void tlb_info_pae32(Monitor *mon, CPUArchState *env, AddressSpace *as)
+static void tlb_info_pae32(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
 {
     const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
     unsigned int l1, l2, l3;
@@ -113,7 +113,7 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env, AddressSpace *as)
                 if (pde & PG_PRESENT_MASK) {
                     if (pde & PG_PSE_MASK) {
                         /* 2M pages with PAE, CR4.PSE is ignored */
-                        print_pte(mon, env, (l1 << 30) + (l2 << 21), pde,
+                        print_pte(hmp, env, (l1 << 30) + (l2 << 21), pde,
                                   ~((hwaddr)(1 << 20) - 1));
                     } else {
                         pt_addr = pde & 0x3fffffffff000ULL;
@@ -121,7 +121,7 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env, AddressSpace *as)
                             pte = address_space_ldq_le(as, pt_addr + l3 * 8,
                                                        attrs, NULL);
                             if (pte & PG_PRESENT_MASK) {
-                                print_pte(mon, env, (l1 << 30) + (l2 << 21)
+                                print_pte(hmp, env, (l1 << 30) + (l2 << 21)
                                           + (l3 << 12),
                                           pte & ~PG_PSE_MASK,
                                           ~(hwaddr)0xfff);
@@ -135,7 +135,7 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env, AddressSpace *as)
 }
 
 #ifdef TARGET_X86_64
-static void tlb_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as,
+static void tlb_info_la48(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as,
         uint64_t l0, uint64_t pml4_addr)
 {
     const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
@@ -158,7 +158,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as,
 
             if (pdpe & PG_PSE_MASK) {
                 /* 1G pages, CR4.PSE is ignored */
-                print_pte(mon, env, (l0 << 48) + (l1 << 39) + (l2 << 30),
+                print_pte(hmp, env, (l0 << 48) + (l1 << 39) + (l2 << 30),
                         pdpe, 0x3ffffc0000000ULL);
                 continue;
             }
@@ -172,7 +172,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as,
 
                 if (pde & PG_PSE_MASK) {
                     /* 2M pages, CR4.PSE is ignored */
-                    print_pte(mon, env, (l0 << 48) + (l1 << 39) + (l2 << 30) +
+                    print_pte(hmp, env, (l0 << 48) + (l1 << 39) + (l2 << 30) +
                             (l3 << 21), pde, 0x3ffffffe00000ULL);
                     continue;
                 }
@@ -182,7 +182,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as,
                     pte = address_space_ldq_le(as, pt_addr + l4 * 8,
                                                attrs, NULL);
                     if (pte & PG_PRESENT_MASK) {
-                        print_pte(mon, env, (l0 << 48) + (l1 << 39) +
+                        print_pte(hmp, env, (l0 << 48) + (l1 << 39) +
                                 (l2 << 30) + (l3 << 21) + (l4 << 12),
                                 pte & ~PG_PSE_MASK, 0x3fffffffff000ULL);
                     }
@@ -192,7 +192,7 @@ static void tlb_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as,
     }
 }
 
-static void tlb_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
+static void tlb_info_la57(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
 {
     const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
     uint64_t l0;
@@ -203,7 +203,7 @@ static void tlb_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
     for (l0 = 0; l0 < 512; l0++) {
         pml5e = address_space_ldq_le(as, pml5_addr + l0 * 8, attrs, NULL);
         if (pml5e & PG_PRESENT_MASK) {
-            tlb_info_la48(mon, env, as, l0, pml5e & 0x3fffffffff000ULL);
+            tlb_info_la48(hmp, env, as, l0, pml5e & 0x3fffffffff000ULL);
         }
     }
 }
@@ -211,18 +211,17 @@ static void tlb_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
 
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     CPUArchState *env;
     AddressSpace *as;
 
     env = monitor_hmp_get_cpu_env(hmp);
     if (!env) {
-        monitor_printf(mon, "No CPU available\n");
+        monitor_hmp_printf(hmp, "No CPU available\n");
         return;
     }
 
     if (!(env->cr[0] & CR0_PG_MASK)) {
-        monitor_printf(mon, "PG disabled\n");
+        monitor_hmp_printf(hmp, "PG disabled\n");
         return;
     }
     as = cpu_get_address_space(env_cpu(env), X86ASIdx_MEM);
@@ -230,21 +229,21 @@ void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 #ifdef TARGET_X86_64
         if (env->hflags & HF_LMA_MASK) {
             if (env->cr[4] & CR4_LA57_MASK) {
-                tlb_info_la57(mon, env, as);
+                tlb_info_la57(hmp, env, as);
             } else {
-                tlb_info_la48(mon, env, as, 0, env->cr[3] & 0x3fffffffff000ULL);
+                tlb_info_la48(hmp, env, as, 0, env->cr[3] & 0x3fffffffff000ULL);
             }
         } else
 #endif
         {
-            tlb_info_pae32(mon, env, as);
+            tlb_info_pae32(hmp, env, as);
         }
     } else {
-        tlb_info_32(mon, env, as);
+        tlb_info_32(hmp, env, as);
     }
 }
 
-static void mem_print(Monitor *mon, CPUArchState *env,
+static void mem_print(MonitorHMP *hmp, CPUArchState *env,
                       hwaddr *pstart, int *plast_prot,
                       hwaddr end, int prot)
 {
@@ -252,14 +251,14 @@ static void mem_print(Monitor *mon, CPUArchState *env,
     prot1 = *plast_prot;
     if (prot != prot1) {
         if (*pstart != -1) {
-            monitor_printf(mon, HWADDR_FMT_plx "-" HWADDR_FMT_plx " "
-                           HWADDR_FMT_plx " %c%c%c\n",
-                           addr_canonical(env, *pstart),
-                           addr_canonical(env, end),
-                           addr_canonical(env, end - *pstart),
-                           prot1 & PG_USER_MASK ? 'u' : '-',
-                           'r',
-                           prot1 & PG_RW_MASK ? 'w' : '-');
+            monitor_hmp_printf(hmp, HWADDR_FMT_plx "-" HWADDR_FMT_plx " "
+                               HWADDR_FMT_plx " %c%c%c\n",
+                               addr_canonical(env, *pstart),
+                               addr_canonical(env, end),
+                               addr_canonical(env, end - *pstart),
+                               prot1 & PG_USER_MASK ? 'u' : '-',
+                               'r',
+                               prot1 & PG_RW_MASK ? 'w' : '-');
         }
         if (prot != 0)
             *pstart = end;
@@ -269,7 +268,7 @@ static void mem_print(Monitor *mon, CPUArchState *env,
     }
 }
 
-static void mem_info_32(Monitor *mon, CPUArchState *env, AddressSpace *as)
+static void mem_info_32(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
 {
     const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
     unsigned int l1, l2;
@@ -286,7 +285,7 @@ static void mem_info_32(Monitor *mon, CPUArchState *env, AddressSpace *as)
         if (pde & PG_PRESENT_MASK) {
             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
                 prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
-                mem_print(mon, env, &start, &last_prot, end, prot);
+                mem_print(hmp, env, &start, &last_prot, end, prot);
             } else {
                 for(l2 = 0; l2 < 1024; l2++) {
                     pte = address_space_ldl_le(as, (pde & ~0xfff) + l2 * 4,
@@ -298,19 +297,19 @@ static void mem_info_32(Monitor *mon, CPUArchState *env, AddressSpace *as)
                     } else {
                         prot = 0;
                     }
-                    mem_print(mon, env, &start, &last_prot, end, prot);
+                    mem_print(hmp, env, &start, &last_prot, end, prot);
                 }
             }
         } else {
             prot = 0;
-            mem_print(mon, env, &start, &last_prot, end, prot);
+            mem_print(hmp, env, &start, &last_prot, end, prot);
         }
     }
     /* Flush last range */
-    mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 32, 0);
+    mem_print(hmp, env, &start, &last_prot, (hwaddr)1 << 32, 0);
 }
 
-static void mem_info_pae32(Monitor *mon, CPUArchState *env, AddressSpace *as)
+static void mem_info_pae32(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
 {
     const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
     unsigned int l1, l2, l3;
@@ -334,7 +333,7 @@ static void mem_info_pae32(Monitor *mon, CPUArchState *env, AddressSpace *as)
                     if (pde & PG_PSE_MASK) {
                         prot = pde & (PG_USER_MASK | PG_RW_MASK |
                                       PG_PRESENT_MASK);
-                        mem_print(mon, env, &start, &last_prot, end, prot);
+                        mem_print(hmp, env, &start, &last_prot, end, prot);
                     } else {
                         pt_addr = pde & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
@@ -347,26 +346,26 @@ static void mem_info_pae32(Monitor *mon, CPUArchState *env, AddressSpace *as)
                             } else {
                                 prot = 0;
                             }
-                            mem_print(mon, env, &start, &last_prot, end, prot);
+                            mem_print(hmp, env, &start, &last_prot, end, prot);
                         }
                     }
                 } else {
                     prot = 0;
-                    mem_print(mon, env, &start, &last_prot, end, prot);
+                    mem_print(hmp, env, &start, &last_prot, end, prot);
                 }
             }
         } else {
             prot = 0;
-            mem_print(mon, env, &start, &last_prot, end, prot);
+            mem_print(hmp, env, &start, &last_prot, end, prot);
         }
     }
     /* Flush last range */
-    mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 32, 0);
+    mem_print(hmp, env, &start, &last_prot, (hwaddr)1 << 32, 0);
 }
 
 
 #ifdef TARGET_X86_64
-static void mem_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as)
+static void mem_info_la48(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
 {
     const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
     int prot, last_prot;
@@ -390,7 +389,7 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as)
                         prot = pdpe & (PG_USER_MASK | PG_RW_MASK |
                                        PG_PRESENT_MASK);
                         prot &= pml4e;
-                        mem_print(mon, env, &start, &last_prot, end, prot);
+                        mem_print(hmp, env, &start, &last_prot, end, prot);
                     } else {
                         pd_addr = pdpe & 0x3fffffffff000ULL;
                         for (l3 = 0; l3 < 512; l3++) {
@@ -402,7 +401,7 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as)
                                     prot = pde & (PG_USER_MASK | PG_RW_MASK |
                                                   PG_PRESENT_MASK);
                                     prot &= pml4e & pdpe;
-                                    mem_print(mon, env, &start,
+                                    mem_print(hmp, env, &start,
                                               &last_prot, end, prot);
                                 } else {
                                     pt_addr = pde & 0x3fffffffff000ULL;
@@ -420,32 +419,32 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env, AddressSpace *as)
                                         } else {
                                             prot = 0;
                                         }
-                                        mem_print(mon, env, &start,
+                                        mem_print(hmp, env, &start,
                                                   &last_prot, end, prot);
                                     }
                                 }
                             } else {
                                 prot = 0;
-                                mem_print(mon, env, &start,
+                                mem_print(hmp, env, &start,
                                           &last_prot, end, prot);
                             }
                         }
                     }
                 } else {
                     prot = 0;
-                    mem_print(mon, env, &start, &last_prot, end, prot);
+                    mem_print(hmp, env, &start, &last_prot, end, prot);
                 }
             }
         } else {
             prot = 0;
-            mem_print(mon, env, &start, &last_prot, end, prot);
+            mem_print(hmp, env, &start, &last_prot, end, prot);
         }
     }
     /* Flush last range */
-    mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 48, 0);
+    mem_print(hmp, env, &start, &last_prot, (hwaddr)1 << 48, 0);
 }
 
-static void mem_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
+static void mem_info_la57(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
 {
     const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
     int prot, last_prot;
@@ -461,7 +460,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
         end = l0 << 48;
         if (!(pml5e & PG_PRESENT_MASK)) {
             prot = 0;
-            mem_print(mon, env, &start, &last_prot, end, prot);
+            mem_print(hmp, env, &start, &last_prot, end, prot);
             continue;
         }
 
@@ -471,7 +470,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
             end = (l0 << 48) + (l1 << 39);
             if (!(pml4e & PG_PRESENT_MASK)) {
                 prot = 0;
-                mem_print(mon, env, &start, &last_prot, end, prot);
+                mem_print(hmp, env, &start, &last_prot, end, prot);
                 continue;
             }
 
@@ -481,7 +480,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
                 end = (l0 << 48) + (l1 << 39) + (l2 << 30);
                 if (pdpe & PG_PRESENT_MASK) {
                     prot = 0;
-                    mem_print(mon, env, &start, &last_prot, end, prot);
+                    mem_print(hmp, env, &start, &last_prot, end, prot);
                     continue;
                 }
 
@@ -489,7 +488,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
                     prot = pdpe & (PG_USER_MASK | PG_RW_MASK |
                             PG_PRESENT_MASK);
                     prot &= pml5e & pml4e;
-                    mem_print(mon, env, &start, &last_prot, end, prot);
+                    mem_print(hmp, env, &start, &last_prot, end, prot);
                     continue;
                 }
 
@@ -500,7 +499,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
                     end = (l0 << 48) + (l1 << 39) + (l2 << 30) + (l3 << 21);
                     if (pde & PG_PRESENT_MASK) {
                         prot = 0;
-                        mem_print(mon, env, &start, &last_prot, end, prot);
+                        mem_print(hmp, env, &start, &last_prot, end, prot);
                         continue;
                     }
 
@@ -508,7 +507,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
                         prot = pde & (PG_USER_MASK | PG_RW_MASK |
                                 PG_PRESENT_MASK);
                         prot &= pml5e & pml4e & pdpe;
-                        mem_print(mon, env, &start, &last_prot, end, prot);
+                        mem_print(hmp, env, &start, &last_prot, end, prot);
                         continue;
                     }
 
@@ -525,31 +524,30 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
                         } else {
                             prot = 0;
                         }
-                        mem_print(mon, env, &start, &last_prot, end, prot);
+                        mem_print(hmp, env, &start, &last_prot, end, prot);
                     }
                 }
             }
         }
     }
     /* Flush last range */
-    mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 57, 0);
+    mem_print(hmp, env, &start, &last_prot, (hwaddr)1 << 57, 0);
 }
 #endif /* TARGET_X86_64 */
 
 void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     CPUArchState *env;
     AddressSpace *as;
 
     env = monitor_hmp_get_cpu_env(hmp);
     if (!env) {
-        monitor_printf(mon, "No CPU available\n");
+        monitor_hmp_printf(hmp, "No CPU available\n");
         return;
     }
 
     if (!(env->cr[0] & CR0_PG_MASK)) {
-        monitor_printf(mon, "PG disabled\n");
+        monitor_hmp_printf(hmp, "PG disabled\n");
         return;
     }
     as = cpu_get_address_space(env_cpu(env), X86ASIdx_MEM);
@@ -557,17 +555,17 @@ void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
 #ifdef TARGET_X86_64
         if (env->hflags & HF_LMA_MASK) {
             if (env->cr[4] & CR4_LA57_MASK) {
-                mem_info_la57(mon, env, as);
+                mem_info_la57(hmp, env, as);
             } else {
-                mem_info_la48(mon, env, as);
+                mem_info_la48(hmp, env, as);
             }
         } else
 #endif
         {
-            mem_info_pae32(mon, env, as);
+            mem_info_pae32(hmp, env, as);
         }
     } else {
-        mem_info_32(mon, env, as);
+        mem_info_32(hmp, env, as);
     }
 }
 
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 4473d02981ff..36a62e58be95 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -756,33 +756,32 @@ SevInfo *qmp_query_sev(Error **errp)
 
 void hmp_info_sev(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     SevInfo *info = sev_get_info();
 
     if (!info || !info->enabled) {
-        monitor_printf(mon, "SEV is not enabled\n");
+        monitor_hmp_printf(hmp, "SEV is not enabled\n");
         goto out;
     }
 
-    monitor_printf(mon, "SEV type: %s\n", SevGuestType_str(info->sev_type));
-    monitor_printf(mon, "state: %s\n", SevState_str(info->state));
-    monitor_printf(mon, "build: %d\n", info->build_id);
-    monitor_printf(mon, "api version: %d.%d\n", info->api_major,
-                   info->api_minor);
+    monitor_hmp_printf(hmp, "SEV type: %s\n", SevGuestType_str(info->sev_type));
+    monitor_hmp_printf(hmp, "state: %s\n", SevState_str(info->state));
+    monitor_hmp_printf(hmp, "build: %d\n", info->build_id);
+    monitor_hmp_printf(hmp, "api version: %d.%d\n", info->api_major,
+                       info->api_minor);
 
     if (sev_snp_enabled()) {
-        monitor_printf(mon, "debug: %s\n",
-                       info->u.sev_snp.snp_policy & SEV_SNP_POLICY_DBG ? "on"
-                                                                       : "off");
-        monitor_printf(mon, "SMT allowed: %s\n",
-                       info->u.sev_snp.snp_policy & SEV_SNP_POLICY_SMT ? "on"
-                                                                       : "off");
+        monitor_hmp_printf(hmp, "debug: %s\n",
+                           info->u.sev_snp.snp_policy & SEV_SNP_POLICY_DBG ? "on"
+                                                                           : "off");
+        monitor_hmp_printf(hmp, "SMT allowed: %s\n",
+                           info->u.sev_snp.snp_policy & SEV_SNP_POLICY_SMT ? "on"
+                                                                           : "off");
     } else {
-        monitor_printf(mon, "handle: %d\n", info->u.sev.handle);
-        monitor_printf(mon, "debug: %s\n",
-                       info->u.sev.policy & SEV_POLICY_NODBG ? "off" : "on");
-        monitor_printf(mon, "key-sharing: %s\n",
-                       info->u.sev.policy & SEV_POLICY_NOKS ? "off" : "on");
+        monitor_hmp_printf(hmp, "handle: %d\n", info->u.sev.handle);
+        monitor_hmp_printf(hmp, "debug: %s\n",
+                           info->u.sev.policy & SEV_POLICY_NODBG ? "off" : "on");
+        monitor_hmp_printf(hmp, "key-sharing: %s\n",
+                           info->u.sev.policy & SEV_POLICY_NOKS ? "off" : "on");
     }
 
 out:
diff --git a/target/m68k/monitor.c b/target/m68k/monitor.c
index 5645a5d4d4f5..23c25283b27a 100644
--- a/target/m68k/monitor.c
+++ b/target/m68k/monitor.c
@@ -12,11 +12,10 @@
 
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
 
     if (!env1) {
-        monitor_printf(mon, "No CPU available\n");
+        monitor_hmp_printf(hmp, "No CPU available\n");
         return;
     }
 
diff --git a/target/ppc/monitor.c b/target/ppc/monitor.c
index 5769829bdd7e..6e8a075f5a41 100644
--- a/target/ppc/monitor.c
+++ b/target/ppc/monitor.c
@@ -13,11 +13,10 @@
 
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
 
     if (!env1) {
-        monitor_printf(mon, "No CPU available\n");
+        monitor_hmp_printf(hmp, "No CPU available\n");
         return;
     }
     dump_mmu(env1);
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
index 4c9c0c793b36..59cc04b3d0fb 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -51,13 +51,13 @@ static target_ulong addr_canonical(int va_bits, target_ulong addr)
     return addr;
 }
 
-static void print_pte_header(Monitor *mon)
+static void print_pte_header(MonitorHMP *hmp)
 {
-    monitor_printf(mon, PTE_HEADER_FIELDS);
-    monitor_printf(mon, PTE_HEADER_DELIMITER);
+    monitor_hmp_printf(hmp, PTE_HEADER_FIELDS);
+    monitor_hmp_printf(hmp, PTE_HEADER_DELIMITER);
 }
 
-static void print_pte(Monitor *mon, int va_bits, target_ulong vaddr,
+static void print_pte(MonitorHMP *hmp, int va_bits, target_ulong vaddr,
                       hwaddr paddr, target_ulong size, int attr)
 {
     /* sanity check on vaddr */
@@ -69,20 +69,20 @@ static void print_pte(Monitor *mon, int va_bits, target_ulong vaddr,
         return;
     }
 
-    monitor_printf(mon, TARGET_FMT_lx " " HWADDR_FMT_plx " " TARGET_FMT_lx
-                   " %c%c%c%c%c%c%c\n",
-                   addr_canonical(va_bits, vaddr),
-                   paddr, size,
-                   attr & PTE_R ? 'r' : '-',
-                   attr & PTE_W ? 'w' : '-',
-                   attr & PTE_X ? 'x' : '-',
-                   attr & PTE_U ? 'u' : '-',
-                   attr & PTE_G ? 'g' : '-',
-                   attr & PTE_A ? 'a' : '-',
-                   attr & PTE_D ? 'd' : '-');
+    monitor_hmp_printf(hmp, TARGET_FMT_lx " " HWADDR_FMT_plx " " TARGET_FMT_lx
+                       " %c%c%c%c%c%c%c\n",
+                       addr_canonical(va_bits, vaddr),
+                       paddr, size,
+                       attr & PTE_R ? 'r' : '-',
+                       attr & PTE_W ? 'w' : '-',
+                       attr & PTE_X ? 'x' : '-',
+                       attr & PTE_U ? 'u' : '-',
+                       attr & PTE_G ? 'g' : '-',
+                       attr & PTE_A ? 'a' : '-',
+                       attr & PTE_D ? 'd' : '-');
 }
 
-static void walk_pte(Monitor *mon, AddressSpace *as,
+static void walk_pte(MonitorHMP *hmp, AddressSpace *as,
                      hwaddr base, target_ulong start,
                      int level, int ptidxbits, int ptesize, int va_bits,
                      target_ulong *vbase, hwaddr *pbase, hwaddr *last_paddr,
@@ -126,7 +126,7 @@ static void walk_pte(Monitor *mon, AddressSpace *as,
                 if ((*last_attr != attr) ||
                     (*last_paddr + *last_size != paddr) ||
                     (last_start + *last_size != start)) {
-                    print_pte(mon, va_bits, *vbase, *pbase,
+                    print_pte(hmp, va_bits, *vbase, *pbase,
                               *last_paddr + *last_size - *pbase, *last_attr);
 
                     *vbase = start;
@@ -139,7 +139,7 @@ static void walk_pte(Monitor *mon, AddressSpace *as,
                 *last_size = pgsize;
             } else {
                 /* pointer to the next level of the page table */
-                walk_pte(mon, as, paddr, start, level - 1, ptidxbits, ptesize,
+                walk_pte(hmp, as, paddr, start, level - 1, ptidxbits, ptesize,
                          va_bits, vbase, pbase, last_paddr,
                          last_size, last_attr);
             }
@@ -150,7 +150,7 @@ static void walk_pte(Monitor *mon, AddressSpace *as,
 
 }
 
-static void mem_info_svxx(Monitor *mon, CPUArchState *env)
+static void mem_info_svxx(MonitorHMP *hmp, CPUArchState *env)
 {
     AddressSpace *as = env_cpu(env)->as;
     int levels, ptidxbits, ptesize, vm, va_bits;
@@ -198,7 +198,7 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
     va_bits = PGSHIFT + levels * ptidxbits;
 
     /* print header */
-    print_pte_header(mon);
+    print_pte_header(hmp);
 
     vbase = -1;
     pbase = -1;
@@ -207,43 +207,42 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
     last_attr = 0;
 
     /* walk page tables, starting from address 0 */
-    walk_pte(mon, as, base, 0, levels - 1, ptidxbits, ptesize, va_bits,
+    walk_pte(hmp, as, base, 0, levels - 1, ptidxbits, ptesize, va_bits,
              &vbase, &pbase, &last_paddr, &last_size, &last_attr);
 
     /* don't forget the last one */
-    print_pte(mon, va_bits, vbase, pbase,
+    print_pte(hmp, va_bits, vbase, pbase,
               last_paddr + last_size - pbase, last_attr);
 }
 
 void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     CPUArchState *env;
 
     env = monitor_hmp_get_cpu_env(hmp);
     if (!env) {
-        monitor_printf(mon, "No CPU available\n");
+        monitor_hmp_printf(hmp, "No CPU available\n");
         return;
     }
 
     if (!riscv_cpu_cfg(env)->mmu) {
-        monitor_printf(mon, "S-mode MMU unavailable\n");
+        monitor_hmp_printf(hmp, "S-mode MMU unavailable\n");
         return;
     }
 
     if (riscv_cpu_mxl(env) == MXL_RV32) {
         if (!(env->satp & SATP32_MODE)) {
-            monitor_printf(mon, "No translation or protection\n");
+            monitor_hmp_printf(hmp, "No translation or protection\n");
             return;
         }
     } else {
         if (!(env->satp & SATP64_MODE)) {
-            monitor_printf(mon, "No translation or protection\n");
+            monitor_hmp_printf(hmp, "No translation or protection\n");
             return;
         }
     }
 
-    mem_info_svxx(mon, env);
+    mem_info_svxx(hmp, env);
 }
 
 #ifdef CONFIG_TCG
diff --git a/target/sh4/monitor.c b/target/sh4/monitor.c
index 4e443152bf56..62998a9a57cb 100644
--- a/target/sh4/monitor.c
+++ b/target/sh4/monitor.c
@@ -26,33 +26,32 @@
 #include "monitor/monitor.h"
 #include "monitor/hmp.h"
 
-static void print_tlb(Monitor *mon, int idx, tlb_t *tlb)
+static void print_tlb(MonitorHMP *hmp, int idx, tlb_t *tlb)
 {
-    monitor_printf(mon, " tlb%i:\t"
-                   "asid=%hhu vpn=%x\tppn=%x\tsz=%hhu size=%u\t"
-                   "v=%hhu shared=%hhu cached=%hhu prot=%hhu "
-                   "dirty=%hhu writethrough=%hhu\n",
-                   idx,
-                   tlb->asid, tlb->vpn, tlb->ppn, tlb->sz, tlb->size,
-                   tlb->v, tlb->sh, tlb->c, tlb->pr,
-                   tlb->d, tlb->wt);
+    monitor_hmp_printf(hmp, " tlb%i:\t"
+                       "asid=%hhu vpn=%x\tppn=%x\tsz=%hhu size=%u\t"
+                       "v=%hhu shared=%hhu cached=%hhu prot=%hhu "
+                       "dirty=%hhu writethrough=%hhu\n",
+                       idx,
+                       tlb->asid, tlb->vpn, tlb->ppn, tlb->sz, tlb->size,
+                       tlb->v, tlb->sh, tlb->c, tlb->pr,
+                       tlb->d, tlb->wt);
 }
 
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     CPUArchState *env = monitor_hmp_get_cpu_env(hmp);
     int i;
 
     if (!env) {
-        monitor_printf(mon, "No CPU available\n");
+        monitor_hmp_printf(hmp, "No CPU available\n");
         return;
     }
 
-    monitor_printf (mon, "ITLB:\n");
+    monitor_hmp_printf(hmp, "ITLB:\n");
     for (i = 0 ; i < ITLB_SIZE ; i++)
-        print_tlb (mon, i, &env->itlb[i]);
-    monitor_printf (mon, "UTLB:\n");
+        print_tlb(hmp, i, &env->itlb[i]);
+    monitor_hmp_printf(hmp, "UTLB:\n");
     for (i = 0 ; i < UTLB_SIZE ; i++)
-        print_tlb (mon, i, &env->utlb[i]);
+        print_tlb(hmp, i, &env->utlb[i]);
 }
diff --git a/target/sparc/monitor.c b/target/sparc/monitor.c
index e826e584a918..36f109cbb568 100644
--- a/target/sparc/monitor.c
+++ b/target/sparc/monitor.c
@@ -29,11 +29,10 @@
 
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
 
     if (!env1) {
-        monitor_printf(mon, "No CPU available\n");
+        monitor_hmp_printf(hmp, "No CPU available\n");
         return;
     }
     dump_mmu(env1);
diff --git a/target/xtensa/monitor.c b/target/xtensa/monitor.c
index b7b7387706f3..b9c4089b0fb1 100644
--- a/target/xtensa/monitor.c
+++ b/target/xtensa/monitor.c
@@ -28,11 +28,10 @@
 
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
 
     if (!env1) {
-        monitor_printf(mon, "No CPU available\n");
+        monitor_hmp_printf(hmp, "No CPU available\n");
         return;
     }
     dump_mmu(env1);
diff --git a/tests/unit/test-util-sockets.c b/tests/unit/test-util-sockets.c
index b2a884529598..530a3fee3c13 100644
--- a/tests/unit/test-util-sockets.c
+++ b/tests/unit/test-util-sockets.c
@@ -75,7 +75,7 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
  */
 Monitor *monitor_cur(void) { return cur_mon; }
 Monitor *monitor_set_cur(Coroutine *co, Monitor *mon) { abort(); }
-int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); }
+int monitor_hmp_vprintf(MonitorHMP *mon, const char *fmt, va_list ap) { abort(); }
 
 #ifndef _WIN32
 static void test_socket_fd_pass_name_good(void)
diff --git a/tools/qemu-vnc/clipboard.c b/tools/qemu-vnc/clipboard.c
index f62b2f294952..81a09ec5adfa 100644
--- a/tools/qemu-vnc/clipboard.c
+++ b/tools/qemu-vnc/clipboard.c
@@ -62,7 +62,7 @@ vnc_dbus_clipboard_request_cancelled(VncDBusClipboardRequest *req)
         "Cancelled clipboard request");
 
     g_clear_object(&req->invocation);
-    g_clear_handle_id(&req->timeout_id, g_source_remove);;
+    g_clear_handle_id(&req->timeout_id, g_source_remove);
 }
 
 static gboolean
@@ -137,7 +137,7 @@ vnc_dbus_clipboard_update_info(QemuClipboardInfo *info)
         vnc_dbus_clipboard_complete_request(
             req->invocation, info, req->type);
         g_clear_object(&req->invocation);
-        g_clear_handle_id(&req->timeout_id, g_source_remove);;
+        g_clear_handle_id(&req->timeout_id, g_source_remove);
         return;
     }
 
diff --git a/tools/qemu-vnc/stubs.c b/tools/qemu-vnc/stubs.c
index 26597fefaa99..0aa50a901d37 100644
--- a/tools/qemu-vnc/stubs.c
+++ b/tools/qemu-vnc/stubs.c
@@ -42,7 +42,7 @@ Monitor *monitor_set_cur(Coroutine *co, Monitor *mon)
     return NULL;
 }
 
-int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
+int monitor_hmp_vprintf(MonitorHMP *mon, const char *fmt, va_list ap)
 {
     return -1;
 }
diff --git a/trace/trace-hmp-cmds.c b/trace/trace-hmp-cmds.c
index 5a8158f4f4b6..a68f5b900d7c 100644
--- a/trace/trace-hmp-cmds.c
+++ b/trace/trace-hmp-cmds.c
@@ -49,7 +49,6 @@ void hmp_trace_event(MonitorHMP *hmp, const QDict *qdict)
 #ifdef CONFIG_TRACE_SIMPLE
 void hmp_trace_file(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *op = qdict_get_try_str(qdict, "op");
     const char *arg = qdict_get_try_str(qdict, "arg");
 
@@ -66,15 +65,14 @@ void hmp_trace_file(MonitorHMP *hmp, const QDict *qdict)
             st_set_trace_file(arg);
         }
     } else {
-        monitor_printf(mon, "unexpected argument \"%s\"\n", op);
-        hmp_help_cmd(mon, "trace-file");
+        monitor_hmp_printf(hmp, "unexpected argument \"%s\"\n", op);
+        hmp_help_cmd(hmp, "trace-file");
     }
 }
 #endif
 
 void hmp_info_trace_events(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *name = qdict_get_try_str(qdict, "name");
     TraceEventInfoList *events;
     TraceEventInfoList *elem;
@@ -91,9 +89,9 @@ void hmp_info_trace_events(MonitorHMP *hmp, const QDict *qdict)
     }
 
     for (elem = events; elem != NULL; elem = elem->next) {
-        monitor_printf(mon, "%s : state %u\n",
-                       elem->value->name,
-                       elem->value->state == TRACE_EVENT_STATE_ENABLED ? 1 : 0);
+        monitor_hmp_printf(hmp, "%s : state %u\n",
+                           elem->value->name,
+                           elem->value->state == TRACE_EVENT_STATE_ENABLED ? 1 : 0);
     }
     qapi_free_TraceEventInfoList(events);
 }
diff --git a/ui/ui-hmp-cmds.c b/ui/ui-hmp-cmds.c
index 186209fd0234..f611dd7ee457 100644
--- a/ui/ui-hmp-cmds.c
+++ b/ui/ui-hmp-cmds.c
@@ -81,20 +81,19 @@ void hmp_mouse_set(MonitorHMP *hmp, const QDict *qdict)
 
 void hmp_info_mice(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     MouseInfoList *mice_list, *mouse;
 
     mice_list = qmp_query_mice(NULL);
     if (!mice_list) {
-        monitor_printf(mon, "No mouse devices connected\n");
+        monitor_hmp_printf(hmp, "No mouse devices connected\n");
         return;
     }
 
     for (mouse = mice_list; mouse; mouse = mouse->next) {
-        monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n",
-                       mouse->value->current ? '*' : ' ',
-                       mouse->value->index, mouse->value->name,
-                       mouse->value->absolute ? " (absolute)" : "");
+        monitor_hmp_printf(hmp, "%c Mouse #%" PRId64 ": %s%s\n",
+                           mouse->value->current ? '*' : ' ',
+                           mouse->value->index, mouse->value->name,
+                           mouse->value->absolute ? " (absolute)" : "");
     }
 
     qapi_free_MouseInfoList(mice_list);
@@ -102,48 +101,48 @@ void hmp_info_mice(MonitorHMP *hmp, const QDict *qdict)
 
 #ifdef CONFIG_VNC
 /* Helper for hmp_info_vnc_clients, _servers */
-static void hmp_info_VncBasicInfo(Monitor *mon, VncBasicInfo *info,
+static void hmp_info_VncBasicInfo(MonitorHMP *hmp, VncBasicInfo *info,
                                   const char *name)
 {
-    monitor_printf(mon, "  %s: %s:%s (%s%s)\n",
-                   name,
-                   info->host,
-                   info->service,
-                   NetworkAddressFamily_str(info->family),
-                   info->websocket ? " (Websocket)" : "");
+    monitor_hmp_printf(hmp, "  %s: %s:%s (%s%s)\n",
+                       name,
+                       info->host,
+                       info->service,
+                       NetworkAddressFamily_str(info->family),
+                       info->websocket ? " (Websocket)" : "");
 }
 
 /* Helper displaying and auth and crypt info */
-static void hmp_info_vnc_authcrypt(Monitor *mon, const char *indent,
+static void hmp_info_vnc_authcrypt(MonitorHMP *hmp, const char *indent,
                                    VncPrimaryAuth auth,
                                    VncVencryptSubAuth *vencrypt)
 {
-    monitor_printf(mon, "%sAuth: %s (Sub: %s)\n", indent,
-                   VncPrimaryAuth_str(auth),
-                   vencrypt ? VncVencryptSubAuth_str(*vencrypt) : "none");
+    monitor_hmp_printf(hmp, "%sAuth: %s (Sub: %s)\n", indent,
+                       VncPrimaryAuth_str(auth),
+                       vencrypt ? VncVencryptSubAuth_str(*vencrypt) : "none");
 }
 
-static void hmp_info_vnc_clients(Monitor *mon, VncClientInfoList *client)
+static void hmp_info_vnc_clients(MonitorHMP *hmp, VncClientInfoList *client)
 {
     while (client) {
         VncClientInfo *cinfo = client->value;
 
-        hmp_info_VncBasicInfo(mon, qapi_VncClientInfo_base(cinfo), "Client");
-        monitor_printf(mon, "    x509_dname: %s\n",
-                       cinfo->x509_dname ?: "none");
-        monitor_printf(mon, "    sasl_username: %s\n",
-                       cinfo->sasl_username ?: "none");
+        hmp_info_VncBasicInfo(hmp, qapi_VncClientInfo_base(cinfo), "Client");
+        monitor_hmp_printf(hmp, "    x509_dname: %s\n",
+                           cinfo->x509_dname ?: "none");
+        monitor_hmp_printf(hmp, "    sasl_username: %s\n",
+                           cinfo->sasl_username ?: "none");
 
         client = client->next;
     }
 }
 
-static void hmp_info_vnc_servers(Monitor *mon, VncServerInfo2List *server)
+static void hmp_info_vnc_servers(MonitorHMP *hmp, VncServerInfo2List *server)
 {
     while (server) {
         VncServerInfo2 *sinfo = server->value;
-        hmp_info_VncBasicInfo(mon, qapi_VncServerInfo2_base(sinfo), "Server");
-        hmp_info_vnc_authcrypt(mon, "    ", sinfo->auth,
+        hmp_info_VncBasicInfo(hmp, qapi_VncServerInfo2_base(sinfo), "Server");
+        hmp_info_vnc_authcrypt(hmp, "    ", sinfo->auth,
                                sinfo->has_vencrypt ? &sinfo->vencrypt : NULL);
         server = server->next;
     }
@@ -151,7 +150,6 @@ static void hmp_info_vnc_servers(Monitor *mon, VncServerInfo2List *server)
 
 void hmp_info_vnc(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     VncInfo2List *info2l, *info2l_head;
     Error *err = NULL;
 
@@ -161,26 +159,26 @@ void hmp_info_vnc(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
     if (!info2l) {
-        monitor_printf(mon, "None\n");
+        monitor_hmp_printf(hmp, "None\n");
         return;
     }
 
     while (info2l) {
         VncInfo2 *info = info2l->value;
-        monitor_printf(mon, "%s:\n", info->id);
-        hmp_info_vnc_servers(mon, info->server);
-        hmp_info_vnc_clients(mon, info->clients);
+        monitor_hmp_printf(hmp, "%s:\n", info->id);
+        hmp_info_vnc_servers(hmp, info->server);
+        hmp_info_vnc_clients(hmp, info->clients);
         if (!info->server) {
             /*
              * The server entry displays its auth, we only need to
              * display in the case of 'reverse' connections where
              * there's no server.
              */
-            hmp_info_vnc_authcrypt(mon, "  ", info->auth,
+            hmp_info_vnc_authcrypt(hmp, "  ", info->auth,
                                info->has_vencrypt ? &info->vencrypt : NULL);
         }
         if (info->display) {
-            monitor_printf(mon, "  Display: %s\n", info->display);
+            monitor_hmp_printf(hmp, "  Display: %s\n", info->display);
         }
         info2l = info2l->next;
     }
@@ -193,7 +191,6 @@ void hmp_info_vnc(MonitorHMP *hmp, const QDict *qdict)
 #ifdef CONFIG_SPICE
 void hmp_info_spice(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     SpiceChannelList *chan;
     SpiceInfo *info;
     const char *channel_name;
@@ -214,38 +211,38 @@ void hmp_info_spice(MonitorHMP *hmp, const QDict *qdict)
     info = qmp_query_spice(NULL);
 
     if (!info->enabled) {
-        monitor_printf(mon, "Server: disabled\n");
+        monitor_hmp_printf(hmp, "Server: disabled\n");
         goto out;
     }
 
-    monitor_printf(mon, "Server:\n");
+    monitor_hmp_printf(hmp, "Server:\n");
     if (info->has_port) {
-        monitor_printf(mon, "     address: %s:%" PRId64 "\n",
-                       info->host, info->port);
+        monitor_hmp_printf(hmp, "     address: %s:%" PRId64 "\n",
+                           info->host, info->port);
     }
     if (info->has_tls_port) {
-        monitor_printf(mon, "     address: %s:%" PRId64 " [tls]\n",
-                       info->host, info->tls_port);
+        monitor_hmp_printf(hmp, "     address: %s:%" PRId64 " [tls]\n",
+                           info->host, info->tls_port);
     }
-    monitor_printf(mon, "    migrated: %s\n",
-                   info->migrated ? "true" : "false");
-    monitor_printf(mon, "        auth: %s\n", info->auth);
-    monitor_printf(mon, "    compiled: %s\n", info->compiled_version);
-    monitor_printf(mon, "  mouse-mode: %s\n",
-                   SpiceQueryMouseMode_str(info->mouse_mode));
+    monitor_hmp_printf(hmp, "    migrated: %s\n",
+                       info->migrated ? "true" : "false");
+    monitor_hmp_printf(hmp, "        auth: %s\n", info->auth);
+    monitor_hmp_printf(hmp, "    compiled: %s\n", info->compiled_version);
+    monitor_hmp_printf(hmp, "  mouse-mode: %s\n",
+                       SpiceQueryMouseMode_str(info->mouse_mode));
 
     if (!info->has_channels || info->channels == NULL) {
-        monitor_printf(mon, "Channels: none\n");
+        monitor_hmp_printf(hmp, "Channels: none\n");
     } else {
         for (chan = info->channels; chan; chan = chan->next) {
-            monitor_printf(mon, "Channel:\n");
-            monitor_printf(mon, "     address: %s:%s%s\n",
-                           chan->value->host, chan->value->port,
-                           chan->value->tls ? " [tls]" : "");
-            monitor_printf(mon, "     session: %" PRId64 "\n",
-                           chan->value->connection_id);
-            monitor_printf(mon, "     channel: %" PRId64 ":%" PRId64 "\n",
-                           chan->value->channel_type, chan->value->channel_id);
+            monitor_hmp_printf(hmp, "Channel:\n");
+            monitor_hmp_printf(hmp, "     address: %s:%s%s\n",
+                               chan->value->host, chan->value->port,
+                               chan->value->tls ? " [tls]" : "");
+            monitor_hmp_printf(hmp, "     session: %" PRId64 "\n",
+                               chan->value->connection_id);
+            monitor_hmp_printf(hmp, "     channel: %" PRId64 ":%" PRId64 "\n",
+                               chan->value->channel_type, chan->value->channel_id);
 
             channel_name = "unknown";
             if (chan->value->channel_type > 0 &&
@@ -254,7 +251,7 @@ void hmp_info_spice(MonitorHMP *hmp, const QDict *qdict)
                 channel_name = channel_names[chan->value->channel_type];
             }
 
-            monitor_printf(mon, "     channel name: %s\n", channel_name);
+            monitor_hmp_printf(hmp, "     channel name: %s\n", channel_name);
         }
     }
 
@@ -333,7 +330,7 @@ static void hmp_change_read_arg(void *opaque, const char *password,
     monitor_hmp_read_command(opaque, 1);
 }
 
-void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
+void hmp_change_vnc(MonitorHMP *hmp, const char *device, const char *target,
                     const char *arg, const char *read_only, bool force,
                     Error **errp)
 {
@@ -346,7 +343,6 @@ void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
         return;
     }
     if (!arg) {
-        MonitorHMP *hmp = MONITOR_HMP(mon);
         monitor_hmp_read_password(hmp, hmp_change_read_arg, NULL);
     } else {
         qmp_change_vnc_password(arg, errp);
@@ -371,7 +367,6 @@ static int index_from_key(const char *key, size_t key_length)
 
 void hmp_sendkey(MonitorHMP *hmp, const QDict *qdict)
 {
-    Monitor *mon = MONITOR(hmp);
     const char *keys = qdict_get_str(qdict, "keys");
     KeyValue *v = NULL;
     KeyValueList *head = NULL, **tail = &head;
@@ -432,7 +427,7 @@ out:
     return;
 
 err_out:
-    monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
+    monitor_hmp_printf(hmp, "invalid parameter: %.*s\n", keyname_len, keys);
     goto out;
 }
 
diff --git a/util/error-report.c b/util/error-report.c
index 70cbd174ffae..c20e157780fa 100644
--- a/util/error-report.c
+++ b/util/error-report.c
@@ -38,7 +38,7 @@ error_vprintf_mon(const char *fmt, va_list ap)
     MonitorHMP *hmp = monitor_cur_hmp();
 
     if (hmp) {
-        return monitor_vprintf(MONITOR(hmp), fmt, ap);
+        return monitor_hmp_vprintf(hmp, fmt, ap);
     }
 
     return vfprintf(stderr, fmt, ap);
diff --git a/util/qemu-print.c b/util/qemu-print.c
index 0eecc05b0330..aabe670fda01 100644
--- a/util/qemu-print.c
+++ b/util/qemu-print.c
@@ -23,7 +23,7 @@ int qemu_vprintf(const char *fmt, va_list ap)
 {
     MonitorHMP *hmp = monitor_cur_hmp();
     if (hmp) {
-        return monitor_vprintf(MONITOR(hmp), fmt, ap);
+        return monitor_hmp_vprintf(hmp, fmt, ap);
     }
     return vprintf(fmt, ap);
 }
@@ -54,7 +54,7 @@ int qemu_vfprintf(FILE *stream, const char *fmt, va_list ap)
 {
     if (!stream) {
         MonitorHMP *hmp = monitor_cur_hmp();
-        return hmp ? monitor_vprintf(MONITOR(hmp), fmt, ap) : -1;
+        return hmp ? monitor_hmp_vprintf(hmp, fmt, ap) : -1;
     }
     return vfprintf(stream, fmt, ap);
 }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 38/49] hexagon: make dump_mmu() take MonitorHMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (36 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 37/49] monitor: tighten monitor_printf*() Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-17  3:49   ` Philippe Mathieu-Daudé
  2026-08-16 19:13 ` [PATCH v3 39/49] qdev-monitor: make print_dev() callback " Marc-André Lureau
                   ` (10 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Brian Cain,
	Pierrick Bouvier

Avoid unsafe MONITOR_HMP() casts.

The function has no caller since its introduction and could
be dropped if it is not wired to a HMP command.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/hexagon/hexagon_tlb.c         | 8 +++-----
 include/hw/hexagon/hexagon_tlb.h | 5 +++--
 target/hexagon/hex_mmu.c         | 4 ++--
 target/hexagon/hex_mmu.h         | 3 ++-
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/hw/hexagon/hexagon_tlb.c b/hw/hexagon/hexagon_tlb.c
index 576929ff224b..584c606a22c5 100644
--- a/hw/hexagon/hexagon_tlb.c
+++ b/hw/hexagon/hexagon_tlb.c
@@ -122,10 +122,8 @@ static inline uint64_t hex_tlb_virt_addr(uint64_t entry)
     return (uint64_t)GET_PTE_VPN(entry) << qemu_target_page_bits();
 }
 
-bool hexagon_tlb_dump_entry(Monitor *mon, uint64_t entry)
+bool hexagon_tlb_dump_entry(MonitorHMP *hmp, uint64_t entry)
 {
-    MonitorHMP *hmp = MONITOR_HMP(mon);
-
     if (GET_PTE_V(entry)) {
         uint64_t PA = hex_tlb_phys_addr(entry);
         uint64_t VA = hex_tlb_virt_addr(entry);
@@ -379,10 +377,10 @@ int hexagon_tlb_check_overlap(HexagonTLBState *tlb, uint64_t entry,
     return -1;
 }
 
-void hexagon_tlb_dump(Monitor *mon, HexagonTLBState *tlb)
+void hexagon_tlb_dump(MonitorHMP *hmp, HexagonTLBState *tlb)
 {
     for (uint32_t i = 0; i < tlb->num_entries; i++) {
-        hexagon_tlb_dump_entry(mon, tlb->entries[i]);
+        hexagon_tlb_dump_entry(hmp, tlb->entries[i]);
     }
 }
 
diff --git a/include/hw/hexagon/hexagon_tlb.h b/include/hw/hexagon/hexagon_tlb.h
index 760dc1ea811b..c3f0fc599fdd 100644
--- a/include/hw/hexagon/hexagon_tlb.h
+++ b/include/hw/hexagon/hexagon_tlb.h
@@ -12,6 +12,7 @@
 #include "qom/object.h"
 #include "exec/hwaddr.h"
 #include "exec/mmu-access-type.h"
+#include "monitor/hmp.h"
 
 #define TYPE_HEXAGON_TLB "hexagon-tlb"
 OBJECT_DECLARE_SIMPLE_TYPE(HexagonTLBState, HEXAGON_TLB)
@@ -37,9 +38,9 @@ uint32_t hexagon_tlb_lookup(HexagonTLBState *tlb, uint32_t asid,
 int hexagon_tlb_check_overlap(HexagonTLBState *tlb, uint64_t entry,
                               uint64_t index);
 
-void hexagon_tlb_dump(Monitor *mon, HexagonTLBState *tlb);
+void hexagon_tlb_dump(MonitorHMP *hmp, HexagonTLBState *tlb);
 
-bool hexagon_tlb_dump_entry(Monitor *mon, uint64_t entry);
+bool hexagon_tlb_dump_entry(MonitorHMP *hmp, uint64_t entry);
 
 uint32_t hexagon_tlb_get_num_entries(HexagonTLBState *tlb);
 
diff --git a/target/hexagon/hex_mmu.c b/target/hexagon/hex_mmu.c
index 81d64a6146cc..242de06eaad2 100644
--- a/target/hexagon/hex_mmu.c
+++ b/target/hexagon/hex_mmu.c
@@ -107,10 +107,10 @@ int hex_tlb_check_overlap(CPUHexagonState *env, uint64_t entry, uint64_t index)
     return hexagon_tlb_check_overlap(cpu->tlb, entry, index);
 }
 
-void dump_mmu(Monitor *mon, CPUHexagonState *env)
+void dump_mmu(MonitorHMP *hmp, CPUHexagonState *env)
 {
     HexagonCPU *cpu = env_archcpu(env);
-    hexagon_tlb_dump(mon, cpu->tlb);
+    hexagon_tlb_dump(hmp, cpu->tlb);
 }
 
 static inline void print_thread(const char *str, CPUState *cs)
diff --git a/target/hexagon/hex_mmu.h b/target/hexagon/hex_mmu.h
index 6aa450b94136..56b2c4a89d0c 100644
--- a/target/hexagon/hex_mmu.h
+++ b/target/hexagon/hex_mmu.h
@@ -10,6 +10,7 @@
 #include "exec/hwaddr.h"
 #include "exec/mmu-access-type.h"
 #include "cpu.h"
+#include "monitor/hmp.h"
 
 extern void hex_tlbw(CPUHexagonState *env, uint32_t index, uint64_t value);
 extern uint32_t hex_tlb_lookup(CPUHexagonState *env, uint32_t ssr, uint32_t VA);
@@ -23,5 +24,5 @@ extern int hex_tlb_check_overlap(CPUHexagonState *env, uint64_t entry,
                                  uint64_t index);
 extern void hex_tlb_lock(CPUHexagonState *env);
 extern void hex_tlb_unlock(CPUHexagonState *env);
-void dump_mmu(Monitor *mon, CPUHexagonState *env);
+void dump_mmu(MonitorHMP *hmp, CPUHexagonState *env);
 #endif

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 39/49] qdev-monitor: make print_dev() callback take MonitorHMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (37 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 38/49] hexagon: make dump_mmu() take MonitorHMP Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-17  3:48   ` Philippe Mathieu-Daudé
  2026-08-16 19:13 ` [PATCH v3 40/49] qapi: make HMP-specific schema entries conditional on CONFIG_HMP Marc-André Lureau
                   ` (9 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Michael S. Tsirkin,
	Laurent Vivier, Amit Shah, Paolo Bonzini, Stefano Stabellini,
	Anthony PERARD, Edgar E. Iglesias, xen-devel

The callback is specific to HMP context, avoid unsafe MONITOR_HMP()
cast.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/char/virtio-serial-bus.c | 6 +++---
 hw/core/sysbus.c            | 5 ++---
 hw/misc/auxbus.c            | 7 +++----
 hw/pci/pci-hmp-cmds.c       | 3 +--
 hw/pci/pci-internal.h       | 2 +-
 hw/usb/bus.c                | 5 ++---
 hw/xen/xen-bus.c            | 3 +--
 include/hw/core/qdev.h      | 3 ++-
 system/qdev-monitor.c       | 7 +++----
 9 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 33fdc0846ac3..4dcc4516e45e 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -814,7 +814,7 @@ static int virtio_serial_load_device(VirtIODevice *vdev, QEMUFile *f,
     return 0;
 }
 
-static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
+static void virtser_bus_dev_print(MonitorHMP *hmp, DeviceState *qdev, int indent);
 
 static const Property virtser_props[] = {
     DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID),
@@ -834,11 +834,11 @@ static const TypeInfo virtser_bus_info = {
     .class_init = virtser_bus_class_init,
 };
 
-static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
+static void virtser_bus_dev_print(MonitorHMP *hmp, DeviceState *qdev, int indent)
 {
     VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(qdev);
 
-    monitor_hmp_printf(MONITOR_HMP(mon), "%*sport %d, guest %s, host %s, throttle %s\n",
+    monitor_hmp_printf(hmp, "%*sport %d, guest %s, host %s, throttle %s\n",
                        indent, "", port->id,
                        port->guest_connected ? "on" : "off",
                        port->host_connected ? "on" : "off",
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 82130ba04698..31c4fdf79d48 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -24,7 +24,7 @@
 #include "monitor/hmp.h"
 #include "system/address-spaces.h"
 
-static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
+static void sysbus_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent);
 static char *sysbus_get_fw_dev_path(DeviceState *dev);
 
 typedef struct SysBusFind {
@@ -249,10 +249,9 @@ bool sysbus_realize_and_unref(SysBusDevice *dev, Error **errp)
     return qdev_realize_and_unref(DEVICE(dev), sysbus_get_default(), errp);
 }
 
-static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent)
+static void sysbus_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent)
 {
     SysBusDevice *s = SYS_BUS_DEVICE(dev);
-    MonitorHMP *hmp = MONITOR_HMP(mon);
     hwaddr size;
     int i;
 
diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
index ffa76f83016b..0bb89c5a60ab 100644
--- a/hw/misc/auxbus.c
+++ b/hw/misc/auxbus.c
@@ -47,7 +47,7 @@
 } while (0)
 
 
-static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent);
+static void aux_slave_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent);
 static inline I2CBus *aux_bridge_get_i2c_bus(AUXTOI2CState *bridge);
 
 /* aux-bus implementation (internal not public) */
@@ -288,7 +288,7 @@ static const TypeInfo aux_to_i2c_type_info = {
 };
 
 /* aux-slave implementation */
-static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent)
+static void aux_slave_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent)
 {
     AUXBus *bus = AUX_BUS(qdev_get_parent_bus(dev));
     AUXSlave *s;
@@ -300,8 +300,7 @@ static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent)
 
     s = AUX_SLAVE(dev);
 
-    monitor_hmp_printf(MONITOR_HMP(mon),
-                       "%*smemory " HWADDR_FMT_plx "/" HWADDR_FMT_plx "\n",
+    monitor_hmp_printf(hmp, "%*smemory " HWADDR_FMT_plx "/" HWADDR_FMT_plx "\n",
                        indent, "",
                        object_property_get_uint(OBJECT(s->mmio), "addr", NULL),
                        memory_region_size(s->mmio));
diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c
index 500f821246a9..bcccfaf07f4d 100644
--- a/hw/pci/pci-hmp-cmds.c
+++ b/hw/pci/pci-hmp-cmds.c
@@ -135,9 +135,8 @@ void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict)
     qapi_free_PciInfoList(info_list);
 }
 
-void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
+void pcibus_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent)
 {
-    MonitorHMP *hmp = MONITOR_HMP(mon);
     PCIDevice *d = (PCIDevice *)dev;
     int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
     const pci_class_desc *desc = get_class_desc(class);
diff --git a/hw/pci/pci-internal.h b/hw/pci/pci-internal.h
index a7d6d8a7324e..b7231fab5dc9 100644
--- a/hw/pci/pci-internal.h
+++ b/hw/pci/pci-internal.h
@@ -16,7 +16,7 @@ extern PCIHostStateList pci_host_bridges;
 
 const pci_class_desc *get_class_desc(int class);
 PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
-void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
+void pcibus_dev_print(MonitorHMP *mon, DeviceState *dev, int indent);
 
 int pcie_aer_parse_error_string(const char *error_name,
                                 uint32_t *status, bool *correctable);
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index fe3dbfa2227c..8bd25a9d872a 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -13,7 +13,7 @@
 #include "trace.h"
 #include "qemu/cutils.h"
 
-static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
+static void usb_bus_dev_print(MonitorHMP *hmp, DeviceState *qdev, int indent);
 
 static char *usb_get_dev_path(DeviceState *dev);
 static char *usb_get_fw_dev_path(DeviceState *qdev);
@@ -544,9 +544,8 @@ static const char *usb_speed(unsigned int speed)
     return txt[speed];
 }
 
-static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
+static void usb_bus_dev_print(MonitorHMP *hmp, DeviceState *qdev, int indent)
 {
-    MonitorHMP *hmp = MONITOR_HMP(mon);
     USBDevice *dev = USB_DEVICE(qdev);
     USBBus *bus = usb_bus_from_device(dev);
 
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 4075b5b001ae..b81a067e7753 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -101,9 +101,8 @@ abort:
     qemu_xen_xs_transaction_end(xenbus->xsh, tid, true);
 }
 
-static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
+static void xen_bus_print_dev(MonitorHMP *hmp, DeviceState *dev, int indent)
 {
-    MonitorHMP *hmp = MONITOR_HMP(mon);
     XenDevice *xendev = XEN_DEVICE(dev);
 
     monitor_hmp_printf(hmp, "%*sname = '%s' frontend_id = %u\n",
diff --git a/include/hw/core/qdev.h b/include/hw/core/qdev.h
index 37f7d3355193..1391dc060caf 100644
--- a/include/hw/core/qdev.h
+++ b/include/hw/core/qdev.h
@@ -10,6 +10,7 @@
 #include "qom/object.h"
 #include "hw/core/hotplug.h"
 #include "hw/core/resettable.h"
+#include "monitor/hmp.h"
 
 /**
  * DOC: The QEMU Device API
@@ -323,7 +324,7 @@ struct BusClass {
     ObjectClass parent_class;
 
     /* FIXME first arg should be BusState */
-    void (*print_dev)(Monitor *mon, DeviceState *dev, int indent);
+    void (*print_dev)(MonitorHMP *mon, DeviceState *dev, int indent);
     /*
      * Return a newly allocated string containing the path of the
      * device on this bus.
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index 3860ada2a237..13ac9f8f3be1 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -790,18 +790,17 @@ static void qdev_print_props(MonitorHMP *hmp, DeviceState *dev, DeviceClass *dc,
     }
 }
 
-static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int indent)
+static void bus_print_dev(BusState *bus, MonitorHMP *hmp, DeviceState *dev, int indent)
 {
     BusClass *bc = BUS_GET_CLASS(bus);
 
     if (bc->print_dev) {
-        bc->print_dev(mon, dev, indent);
+        bc->print_dev(hmp, dev, indent);
     }
 }
 
 static void qdev_print(MonitorHMP *hmp, DeviceState *dev, int indent)
 {
-    Monitor *mon = MONITOR(hmp);
     ObjectClass *class;
     NamedGPIOList *ngl;
     NamedClockList *ncl;
@@ -828,7 +827,7 @@ static void qdev_print(MonitorHMP *hmp, DeviceState *dev, int indent)
         qdev_print_props(hmp, dev, DEVICE_CLASS(class), indent);
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
-    bus_print_dev(dev->parent_bus, mon, dev, indent);
+    bus_print_dev(dev->parent_bus, hmp, dev, indent);
 }
 
 static void qbus_print(MonitorHMP *hmp, BusState *bus, int indent, bool details)

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 40/49] qapi: make HMP-specific schema entries conditional on CONFIG_HMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (38 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 39/49] qdev-monitor: make print_dev() callback " Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-16 19:13 ` [PATCH v3 41/49] Guard HMP command implementations with CONFIG_HMP Marc-André Lureau
                   ` (8 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Dr. David Alan Gilbert, Eric Blake

Make the 'readline' value of MonitorMode and the
'human-monitor-command' command conditional on CONFIG_HMP, so
they are only available when HMP support is compiled in.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 monitor/monitor.c  | 8 +++++++-
 monitor/qmp-cmds.c | 2 ++
 qapi/control.json  | 4 +++-
 qapi/misc.json     | 3 ++-
 4 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/monitor/monitor.c b/monitor/monitor.c
index da76e6e4ac19..da0c8eda86b0 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -740,13 +740,18 @@ int monitor_new(MonitorOptions *opts, bool allow_hmp, Error **errp)
     ERRP_GUARD();
 
     if (!opts->has_mode) {
-        opts->mode = allow_hmp ? MONITOR_MODE_READLINE : MONITOR_MODE_CONTROL;
+        opts->mode =
+#ifdef CONFIG_HMP
+            allow_hmp ? MONITOR_MODE_READLINE :
+#endif
+            MONITOR_MODE_CONTROL;
     }
 
     switch (opts->mode) {
     case MONITOR_MODE_CONTROL:
         monitor_new_qmp(opts->id, opts->chardev, opts->pretty, errp);
         break;
+#ifdef CONFIG_HMP
     case MONITOR_MODE_READLINE:
         if (!allow_hmp) {
             error_setg(errp, "Only QMP is supported");
@@ -758,6 +763,7 @@ int monitor_new(MonitorOptions *opts, bool allow_hmp, Error **errp)
         }
         monitor_new_hmp(opts->id, opts->chardev, true, errp);
         break;
+#endif /* CONFIG_HMP */
     default:
         g_assert_not_reached();
     }
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index b16119f4858c..c9f24febdc96 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -162,6 +162,7 @@ void qmp_add_client(const char *protocol, const char *fdname,
     }
 }
 
+#ifdef CONFIG_HMP
 char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
                                 int64_t cpu_index, Error **errp)
 {
@@ -187,6 +188,7 @@ out:
     object_unref(hmp);
     return output;
 }
+#endif /* CONFIG_HMP */
 
 static void __attribute__((__constructor__)) monitor_init_qmp_commands(void)
 {
diff --git a/qapi/control.json b/qapi/control.json
index 9a5302193d67..9898552814b1 100644
--- a/qapi/control.json
+++ b/qapi/control.json
@@ -186,7 +186,9 @@
 #
 # Since: 5.0
 ##
-{ 'enum': 'MonitorMode', 'data': [ 'readline', 'control' ] }
+{ 'enum': 'MonitorMode', 'data': [
+    { 'name': 'readline', 'if': 'CONFIG_HMP' },
+    'control' ] }
 
 ##
 # @MonitorOptions:
diff --git a/qapi/misc.json b/qapi/misc.json
index 22b7afed9f65..a21ba61b96e0 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -247,7 +247,8 @@
 { 'command': 'human-monitor-command',
   'data': {'command-line': 'str', '*cpu-index': 'int'},
   'returns': 'str',
-  'features': [ 'savevm-monitor-nodes' ] }
+  'features': [ 'savevm-monitor-nodes' ],
+  'if': 'CONFIG_HMP' }
 
 ##
 # @getfd:

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 41/49] Guard HMP command implementations with CONFIG_HMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (39 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 40/49] qapi: make HMP-specific schema entries conditional on CONFIG_HMP Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-17 18:11   ` Jason J. Herne
  2026-08-16 19:13 ` [PATCH v3 42/49] target: guard MonitorDef tables " Marc-André Lureau
                   ` (7 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Richard Henderson,
	Paolo Bonzini, David Woodhouse, Paul Durrant, Michael S. Tsirkin,
	Marcelo Tosatti, Mark Cave-Ayland, Halil Pasic,
	Christian Borntraeger, Jason Herne, Eric Farman, Matthew Rosato,
	Ilya Leoshkevich, David Hildenbrand, Cornelia Huck, Gerd Hoffmann,
	Hyman Huang, Peter Xu, Fabiano Rosas, Dr. David Alan Gilbert,
	Samuel Thibault, Jason Wang, Alex Bennée, Zhao Liu,
	Laurent Vivier, Nicholas Piggin, Chinmay Rath, Glenn Miles,
	Harsh Prateek Bora, Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Yoshinori Sato,
	Artyom Tarasenko, Max Filippov, kvm, qemu-ppc, qemu-s390x,
	qemu-riscv

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: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 accel/accel-system.c      | 2 ++
 accel/tcg/monitor.c       | 2 ++
 hw/i386/kvm/xen-stubs.c   | 2 ++
 hw/i386/kvm/xen_evtchn.c  | 3 +++
 hw/i386/sgx.c             | 2 ++
 hw/misc/mos6522-stub.c    | 2 ++
 hw/misc/mos6522.c         | 2 ++
 hw/pci/pci-stub.c         | 2 ++
 hw/s390x/s390-skeys.c     | 2 ++
 hw/s390x/s390-stattrib.c  | 4 ++++
 hw/uefi/ovmf-log.c        | 2 ++
 hw/usb/host-libusb.c      | 6 ++++++
 migration/dirtyrate.c     | 2 ++
 monitor/hmp-cmds.c        | 5 +++++
 net/slirp.c               | 7 ++++++-
 replay/replay-debugging.c | 8 ++++++++
 replay/stubs-system.c     | 6 ++++++
 system/qdev-monitor.c     | 4 ++++
 target/i386/cpu-apic.c    | 2 ++
 target/i386/monitor.c     | 3 +++
 target/i386/sev.c         | 2 ++
 target/m68k/monitor.c     | 2 ++
 target/ppc/monitor.c      | 2 ++
 target/riscv/monitor.c    | 3 +++
 target/sh4/monitor.c      | 2 ++
 target/sparc/monitor.c    | 2 ++
 target/xtensa/monitor.c   | 2 ++
 27 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/accel/accel-system.c b/accel/accel-system.c
index 977804c4048a..1325b23864c8 100644
--- a/accel/accel-system.c
+++ b/accel/accel-system.c
@@ -109,7 +109,9 @@ void accel_init_ops_interfaces(AccelClass *ac)
 
 static void accel_ops_class_init(ObjectClass *oc, const void *data)
 {
+#ifdef CONFIG_HMP
     monitor_register_hmp_info_hrt("accel", qmp_x_accel_stats);
+#endif
 }
 
 static const TypeInfo accel_ops_type_info = {
diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c
index 74170ddef708..5570d60753d6 100644
--- a/accel/tcg/monitor.c
+++ b/accel/tcg/monitor.c
@@ -30,9 +30,11 @@ HumanReadableText *qmp_x_query_jit(Error **errp)
     return human_readable_text_from_str(buf);
 }
 
+#ifdef CONFIG_HMP
 static void hmp_tcg_register(void)
 {
     monitor_register_hmp_info_hrt("jit", qmp_x_query_jit);
 }
 
 type_init(hmp_tcg_register);
+#endif
diff --git a/hw/i386/kvm/xen-stubs.c b/hw/i386/kvm/xen-stubs.c
index 5ed71583281a..a68c739a9496 100644
--- a/hw/i386/kvm/xen-stubs.c
+++ b/hw/i386/kvm/xen-stubs.c
@@ -40,6 +40,7 @@ void xen_primary_console_set_be_port(uint16_t port)
 {
 }
 
+#ifdef CONFIG_HMP
 void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict)
 {
     monitor_hmp_printf(hmp, "XEN emulation is not available in this QEMU\n");
@@ -49,3 +50,4 @@ void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict)
 {
     monitor_hmp_printf(hmp, "XEN emulation is not available in this QEMU\n");
 }
+#endif
diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c
index b2135020f27f..9379383e5325 100644
--- a/hw/i386/kvm/xen_evtchn.c
+++ b/hw/i386/kvm/xen_evtchn.c
@@ -2344,6 +2344,7 @@ void qmp_xen_event_inject(uint32_t port, Error **errp)
     }
 }
 
+#ifdef CONFIG_HMP
 void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict)
 {
     EvtchnInfoList *iter, *info_list;
@@ -2391,3 +2392,5 @@ void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict)
         monitor_hmp_printf(hmp, "Delivered port %d\n", port);
     }
 }
+
+#endif
diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
index 634e33e819ce..11bcc7ad9a5a 100644
--- a/hw/i386/sgx.c
+++ b/hw/i386/sgx.c
@@ -234,6 +234,7 @@ SgxInfo *qmp_query_sgx(Error **errp)
     return info;
 }
 
+#ifdef CONFIG_HMP
 void hmp_info_sgx(MonitorHMP *hmp, const QDict *qdict)
 {
     Error *err = NULL;
@@ -265,6 +266,7 @@ void hmp_info_sgx(MonitorHMP *hmp, const QDict *qdict)
     monitor_hmp_printf(hmp, "total size=%" PRIu64 "\n",
                        size);
 }
+#endif
 
 bool check_sgx_support(void)
 {
diff --git a/hw/misc/mos6522-stub.c b/hw/misc/mos6522-stub.c
index 154cd32ed88b..d1c141450e67 100644
--- a/hw/misc/mos6522-stub.c
+++ b/hw/misc/mos6522-stub.c
@@ -10,7 +10,9 @@
 #include "monitor/monitor.h"
 #include "monitor/hmp.h"
 
+#ifdef CONFIG_HMP
 void hmp_info_via(MonitorHMP *hmp, const QDict *qdict)
 {
     monitor_hmp_printf(hmp, "MOS6522 VIA is not available in this QEMU\n");
 }
+#endif
diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index 1c20c7582c34..3135761a0f7b 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -497,6 +497,7 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
     }
 }
 
+#ifdef CONFIG_HMP
 static int qmp_x_query_via_foreach(Object *obj, void *opaque)
 {
     GString *buf = opaque;
@@ -597,6 +598,7 @@ void hmp_info_via(MonitorHMP *hmp, const QDict *qdict)
     }
     monitor_puts(mon, info->human_readable_text);
 }
+#endif /* CONFIG_HMP */
 
 static const MemoryRegionOps mos6522_ops = {
     .read = mos6522_read,
diff --git a/hw/pci/pci-stub.c b/hw/pci/pci-stub.c
index 7e2797300ba0..5fc3322627e3 100644
--- a/hw/pci/pci-stub.c
+++ b/hw/pci/pci-stub.c
@@ -34,6 +34,7 @@ PciInfoList *qmp_query_pci(Error **errp)
     return NULL;
 }
 
+#ifdef CONFIG_HMP
 void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict)
 {
 }
@@ -42,6 +43,7 @@ void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict)
 {
     monitor_hmp_printf(hmp, "PCI devices not supported\n");
 }
+#endif
 
 /* kvm-all wants this */
 MSIMessage pci_get_msi_message(PCIDevice *dev, int vector)
diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
index b5e56a16cce1..c615c9dbc8a1 100644
--- a/hw/s390x/s390-skeys.c
+++ b/hw/s390x/s390-skeys.c
@@ -104,6 +104,7 @@ static void write_keys(FILE *f, uint8_t *keys, uint64_t startgfn,
     }
 }
 
+#ifdef CONFIG_HMP
 void hmp_info_skeys(MonitorHMP *hmp, const QDict *qdict)
 {
     S390SKeysState *ss = s390_get_skeys_device();
@@ -144,6 +145,7 @@ void hmp_dump_skeys(MonitorHMP *hmp, const QDict *qdict)
         error_report_err(err);
     }
 }
+#endif
 
 void s390_qmp_dump_skeys(const char *filename, Error **errp)
 {
diff --git a/hw/s390x/s390-stattrib.c b/hw/s390x/s390-stattrib.c
index 644298f7f0b2..e47a8ea36597 100644
--- a/hw/s390x/s390-stattrib.c
+++ b/hw/s390x/s390-stattrib.c
@@ -32,6 +32,7 @@
 #define STATTR_FLAG_ERROR   0x04ULL
 #define STATTR_FLAG_DONE    0x08ULL
 
+#ifdef CONFIG_HMP
 static S390StAttribState *s390_get_stattrib_device(void)
 {
     S390StAttribState *sas;
@@ -40,6 +41,7 @@ static S390StAttribState *s390_get_stattrib_device(void)
     assert(sas);
     return sas;
 }
+#endif
 
 void s390_stattrib_init(void)
 {
@@ -59,6 +61,7 @@ void s390_stattrib_init(void)
 
 /* Console commands: */
 
+#ifdef CONFIG_HMP
 void hmp_migrationmode(MonitorHMP *hmp, const QDict *qdict)
 {
     S390StAttribState *sas = s390_get_stattrib_device();
@@ -110,6 +113,7 @@ void hmp_info_cmma(MonitorHMP *hmp, const QDict *qdict)
 out:
     g_free(vals);
 }
+#endif
 
 /* Migration support: */
 
diff --git a/hw/uefi/ovmf-log.c b/hw/uefi/ovmf-log.c
index 0249eea2cfe9..c4e6a5064106 100644
--- a/hw/uefi/ovmf-log.c
+++ b/hw/uefi/ovmf-log.c
@@ -256,6 +256,7 @@ FirmwareLog *qmp_query_firmware_log(bool have_max_size, uint64_t max_size,
     return ret;
 }
 
+#ifdef CONFIG_HMP
 void hmp_info_firmware_log(MonitorHMP *hmp, const QDict *qdict)
 {
     g_autofree gchar *log_esc = NULL;
@@ -284,3 +285,4 @@ void hmp_info_firmware_log(MonitorHMP *hmp, const QDict *qdict)
     log_esc = g_strescape((gchar *)log_out, "\r\n");
     monitor_hmp_printf(hmp, "%s\n", log_esc);
 }
+#endif
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 9b9f26a1078e..564fe9a54795 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -184,6 +184,7 @@ static void usb_host_attach_kernel(USBHostDevice *s);
 # define HAVE_SUPER_PLUS 1
 #endif
 
+#ifdef CONFIG_HMP
 static const char *speed_name[] = {
     [LIBUSB_SPEED_UNKNOWN] = "?",
     [LIBUSB_SPEED_LOW]     = "1.5",
@@ -194,6 +195,7 @@ static const char *speed_name[] = {
     [LIBUSB_SPEED_SUPER_PLUS] = "5000+",
 #endif
 };
+#endif
 
 static const unsigned int speed_map[] = {
     [LIBUSB_SPEED_LOW]     = USB_SPEED_LOW,
@@ -1815,7 +1817,9 @@ module_kconfig(USB);
 static void usb_host_register_types(void)
 {
     type_register_static(&usb_host_dev_info);
+#ifdef CONFIG_HMP
     monitor_register_hmp("usbhost", true, hmp_info_usbhost);
+#endif
 }
 
 type_init(usb_host_register_types)
@@ -1920,6 +1924,7 @@ static void usb_host_auto_check(void *unused)
     timer_mod(usb_auto_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 2000);
 }
 
+#ifdef CONFIG_HMP
 void hmp_info_usbhost(MonitorHMP *hmp, const QDict *qdict)
 {
     libusb_device **devs = NULL;
@@ -1963,3 +1968,4 @@ void hmp_info_usbhost(MonitorHMP *hmp, const QDict *qdict)
     }
     libusb_free_device_list(devs, 1);
 }
+#endif
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index bdbb2aaa99db..776611fef79c 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -856,6 +856,7 @@ struct DirtyRateInfo *qmp_query_dirty_rate(bool has_calc_time_unit,
         has_calc_time_unit ? calc_time_unit : TIME_UNIT_SECOND);
 }
 
+#ifdef CONFIG_HMP
 void hmp_info_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
 {
     DirtyRateInfo *info = query_dirty_rate_info(TIME_UNIT_SECOND);
@@ -932,3 +933,4 @@ void hmp_calc_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
                        " seconds\n", sec);
     monitor_hmp_printf(hmp, "[Please use 'info dirty_rate' to check results]\n");
 }
+#endif
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 1834e3c1f697..3ac70c3f1123 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -42,6 +42,7 @@
 #include "disas/disas.h"
 
 /* Please update hmp-commands.hx when adding or changing commands */
+#ifdef CONFIG_HMP
 static HMPCommand hmp_info_cmds[] = {
 #include "hmp-commands-info.h"
     { NULL, NULL, },
@@ -52,6 +53,10 @@ static HMPCommand hmp_cmds[] = {
 #include "hmp-commands.h"
     { NULL, NULL, },
 };
+#else
+static HMPCommand hmp_info_cmds[] = { { NULL, NULL, }, };
+static HMPCommand hmp_cmds[] = { { NULL, NULL, }, };
+#endif
 
 HMPCommand *hmp_cmds_for_target(bool info_command)
 {
diff --git a/net/slirp.c b/net/slirp.c
index 6fbefa9ed1d7..451c0fd1ba4a 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -711,6 +711,7 @@ error:
     return -1;
 }
 
+#ifdef CONFIG_HMP
 static SlirpState *slirp_lookup(MonitorHMP *hmp, const char *id)
 {
     if (id) {
@@ -801,6 +802,7 @@ void hmp_hostfwd_remove(MonitorHMP *hmp, const QDict *qdict)
  fail_syntax:
     monitor_hmp_printf(hmp, "invalid format\n");
 }
+#endif
 
 static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
 {
@@ -957,6 +959,7 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
     return -1;
 }
 
+#ifdef CONFIG_HMP
 void hmp_hostfwd_add(MonitorHMP *hmp, const QDict *qdict)
 {
     const char *redir_str;
@@ -977,8 +980,8 @@ void hmp_hostfwd_add(MonitorHMP *hmp, const QDict *qdict)
             error_report_err(err);
         }
     }
-
 }
+#endif
 
 #if defined(CONFIG_SMBD_COMMAND)
 
@@ -1224,6 +1227,7 @@ UsernetInfoList *qmp_x_query_usernet(Error **errp)
     return head;
 }
 
+#ifdef CONFIG_HMP
 void hmp_info_usernet(MonitorHMP *hmp, const QDict *qdict)
 {
     g_autoptr(UsernetInfoList) list = NULL;
@@ -1237,6 +1241,7 @@ void hmp_info_usernet(MonitorHMP *hmp, const QDict *qdict)
                            ui->hub_name, ui->info);
     }
 }
+#endif
 
 static void
 net_init_slirp_configs_host(const NetdevUserHostForwardList *fwd)
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
index 965565715ef2..4b741ea1027b 100644
--- a/replay/replay-debugging.c
+++ b/replay/replay-debugging.c
@@ -31,6 +31,7 @@ bool replay_running_debug(void)
     return replay_is_debugging;
 }
 
+#ifdef CONFIG_HMP
 void hmp_info_replay(MonitorHMP *hmp, const QDict *qdict)
 {
     if (replay_mode == REPLAY_MODE_NONE) {
@@ -42,6 +43,7 @@ void hmp_info_replay(MonitorHMP *hmp, const QDict *qdict)
             replay_get_filename(), replay_get_current_icount());
     }
 }
+#endif
 
 ReplayInfo *qmp_query_replay(Error **errp)
 {
@@ -103,6 +105,7 @@ void qmp_replay_break(int64_t icount, Error **errp)
     }
 }
 
+#ifdef CONFIG_HMP
 void hmp_replay_break(MonitorHMP *hmp, const QDict *qdict)
 {
     int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
@@ -114,6 +117,7 @@ void hmp_replay_break(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 }
+#endif
 
 void qmp_replay_delete_break(Error **errp)
 {
@@ -124,6 +128,7 @@ void qmp_replay_delete_break(Error **errp)
     }
 }
 
+#ifdef CONFIG_HMP
 void hmp_replay_delete_break(MonitorHMP *hmp, const QDict *qdict)
 {
     Error *err = NULL;
@@ -134,6 +139,7 @@ void hmp_replay_delete_break(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 }
+#endif
 
 static char *replay_find_nearest_snapshot(int64_t icount,
                                           int64_t *snapshot_icount)
@@ -209,6 +215,7 @@ void qmp_replay_seek(int64_t icount, Error **errp)
     replay_seek(icount, replay_stop_vm, errp);
 }
 
+#ifdef CONFIG_HMP
 void hmp_replay_seek(MonitorHMP *hmp, const QDict *qdict)
 {
     int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
@@ -220,6 +227,7 @@ void hmp_replay_seek(MonitorHMP *hmp, const QDict *qdict)
         return;
     }
 }
+#endif
 
 static void replay_stop_vm_debug(void *opaque)
 {
diff --git a/replay/stubs-system.c b/replay/stubs-system.c
index 15e7411591ab..70eaf1834032 100644
--- a/replay/stubs-system.c
+++ b/replay/stubs-system.c
@@ -63,22 +63,28 @@ void replay_vmstate_init(void)
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 
+#ifdef CONFIG_HMP
 void hmp_info_replay(MonitorHMP *hmp, const QDict *qdict)
 {
     error_report("replay support not available");
 }
+
 void hmp_replay_break(MonitorHMP *hmp, const QDict *qdict)
 {
     error_report("replay support not available");
 }
+
 void hmp_replay_delete_break(MonitorHMP *hmp, const QDict *qdict)
 {
     error_report("replay support not available");
 }
+
 void hmp_replay_seek(MonitorHMP *hmp, const QDict *qdict)
 {
     error_report("replay support not available");
 }
+#endif
+
 ReplayInfo *qmp_query_replay(Error **errp)
 {
     error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index 13ac9f8f3be1..5c87fda50939 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -763,6 +763,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
     return ret;
 }
 
+#ifdef CONFIG_HMP
 #define qdev_printf(fmt, ...) \
     monitor_hmp_printf(hmp, "%*s" fmt, indent, "", ## __VA_ARGS__)
 
@@ -865,6 +866,7 @@ void hmp_info_qdm(MonitorHMP *hmp, const QDict *qdict)
 {
     qdev_print_devinfos(true);
 }
+#endif /* CONFIG_HMP */
 
 void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
 {
@@ -1002,6 +1004,7 @@ void qmp_device_sync_config(const char *id, Error **errp)
     qdev_sync_config(dev, errp);
 }
 
+#ifdef CONFIG_HMP
 void hmp_device_add(MonitorHMP *hmp, const QDict *qdict)
 {
     Error *err = NULL;
@@ -1044,6 +1047,7 @@ void hmp_device_del(MonitorHMP *hmp, const QDict *qdict)
     qmp_device_del(id, &err);
     hmp_handle_error(hmp, err);
 }
+#endif
 
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
 {
diff --git a/target/i386/cpu-apic.c b/target/i386/cpu-apic.c
index 5d69ece15034..b6ddb5e268de 100644
--- a/target/i386/cpu-apic.c
+++ b/target/i386/cpu-apic.c
@@ -80,6 +80,7 @@ void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
      }
 }
 
+#ifdef CONFIG_HMP
 void hmp_info_local_apic(MonitorHMP *hmp, const QDict *qdict)
 {
     CPUState *cs;
@@ -102,3 +103,4 @@ void hmp_info_local_apic(MonitorHMP *hmp, const QDict *qdict)
     }
     x86_cpu_dump_local_apic_state(cs, CPU_DUMP_FPU);
 }
+#endif
diff --git a/target/i386/monitor.c b/target/i386/monitor.c
index 46762540ba65..ce61132e0f53 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -31,6 +31,8 @@
 #include "qapi/qapi-commands-misc.h"
 #include "system/memory.h"
 
+#ifdef CONFIG_HMP
+
 /* Perform linear address sign extension */
 static hwaddr addr_canonical(CPUArchState *env, hwaddr addr)
 {
@@ -595,3 +597,4 @@ void hmp_mce(MonitorHMP *hmp, const QDict *qdict)
     }
     hmp_handle_error(hmp, err);
 }
+#endif
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 36a62e58be95..3c6a19b79784 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -754,6 +754,7 @@ SevInfo *qmp_query_sev(Error **errp)
     return info;
 }
 
+#ifdef CONFIG_HMP
 void hmp_info_sev(MonitorHMP *hmp, const QDict *qdict)
 {
     SevInfo *info = sev_get_info();
@@ -787,6 +788,7 @@ void hmp_info_sev(MonitorHMP *hmp, const QDict *qdict)
 out:
     qapi_free_SevInfo(info);
 }
+#endif
 
 static int
 sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain,
diff --git a/target/m68k/monitor.c b/target/m68k/monitor.c
index 23c25283b27a..e8b1b25a43c4 100644
--- a/target/m68k/monitor.c
+++ b/target/m68k/monitor.c
@@ -10,6 +10,7 @@
 #include "monitor/hmp.h"
 #include "monitor/monitor.h"
 
+#ifdef CONFIG_HMP
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
     CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
@@ -21,3 +22,4 @@ void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 
     dump_mmu(env1);
 }
+#endif
diff --git a/target/ppc/monitor.c b/target/ppc/monitor.c
index 6e8a075f5a41..5a21c01593b9 100644
--- a/target/ppc/monitor.c
+++ b/target/ppc/monitor.c
@@ -11,6 +11,7 @@
 #include "monitor/hmp.h"
 #include "cpu.h"
 
+#ifdef CONFIG_HMP
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
     CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
@@ -21,3 +22,4 @@ void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
     }
     dump_mmu(env1);
 }
+#endif
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
index 59cc04b3d0fb..7e61ae2a4717 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -39,6 +39,8 @@
 #define PTE_HEADER_DELIMITER    "-------- ---------------- -------- -------\n"
 #endif
 
+#ifdef CONFIG_HMP
+
 /* Perform linear address sign extension */
 static target_ulong addr_canonical(int va_bits, target_ulong addr)
 {
@@ -244,6 +246,7 @@ void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
 
     mem_info_svxx(hmp, env);
 }
+#endif /* CONFIG_HMP */
 
 #ifdef CONFIG_TCG
 static bool reg_is_ulong_integer(CPURISCVState *env, const char *name,
diff --git a/target/sh4/monitor.c b/target/sh4/monitor.c
index 62998a9a57cb..14261c059706 100644
--- a/target/sh4/monitor.c
+++ b/target/sh4/monitor.c
@@ -26,6 +26,7 @@
 #include "monitor/monitor.h"
 #include "monitor/hmp.h"
 
+#ifdef CONFIG_HMP
 static void print_tlb(MonitorHMP *hmp, int idx, tlb_t *tlb)
 {
     monitor_hmp_printf(hmp, " tlb%i:\t"
@@ -55,3 +56,4 @@ void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
     for (i = 0 ; i < UTLB_SIZE ; i++)
         print_tlb(hmp, i, &env->utlb[i]);
 }
+#endif
diff --git a/target/sparc/monitor.c b/target/sparc/monitor.c
index 36f109cbb568..ed1e76fe73f8 100644
--- a/target/sparc/monitor.c
+++ b/target/sparc/monitor.c
@@ -27,6 +27,7 @@
 #include "monitor/hmp.h"
 
 
+#ifdef CONFIG_HMP
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
     CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
@@ -37,3 +38,4 @@ void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
     }
     dump_mmu(env1);
 }
+#endif
diff --git a/target/xtensa/monitor.c b/target/xtensa/monitor.c
index b9c4089b0fb1..e0fcac8565dc 100644
--- a/target/xtensa/monitor.c
+++ b/target/xtensa/monitor.c
@@ -26,6 +26,7 @@
 #include "monitor/monitor.h"
 #include "monitor/hmp.h"
 
+#ifdef CONFIG_HMP
 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
 {
     CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
@@ -36,3 +37,4 @@ void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
     }
     dump_mmu(env1);
 }
+#endif

-- 
2.55.0.543.g5ebe2ebe4ea8


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

* [PATCH v3 42/49] target: guard MonitorDef tables with CONFIG_HMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (40 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 41/49] Guard HMP command implementations with CONFIG_HMP Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-17  3:47   ` Philippe Mathieu-Daudé
  2026-08-16 19:13 ` [PATCH v3 43/49] hw: guard BusClass::print_dev " Marc-André Lureau
                   ` (6 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Dr. David Alan Gilbert, Paolo Bonzini, Zhao Liu, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko

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.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/hw/core/sysemu-cpu-ops.h | 2 ++
 monitor/hmp.c                    | 4 +++-
 target/i386/cpu.c                | 4 ++++
 target/m68k/cpu.c                | 4 ++++
 target/sparc/cpu.c               | 5 +++--
 5 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/include/hw/core/sysemu-cpu-ops.h b/include/hw/core/sysemu-cpu-ops.h
index 9a45596169a3..e56eea18b785 100644
--- a/include/hw/core/sysemu-cpu-ops.h
+++ b/include/hw/core/sysemu-cpu-ops.h
@@ -109,11 +109,13 @@ typedef struct SysemuCPUOps {
      */
     int (*monitor_get_register)(CPUState *cs, const char *name, int64_t *pval);
 
+#ifdef CONFIG_HMP
     /**
      * @monitor_defs: Array of MonitorDef entries. This field is legacy,
      *                use @gdb_core_xml_file to dump registers instead.
      */
     const MonitorDef *monitor_defs;
+#endif
 
     /**
      * @legacy_vmsd: Legacy state for migration.
diff --git a/monitor/hmp.c b/monitor/hmp.c
index e5f8b9c576e0..3c70adcd35bb 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -1725,13 +1725,15 @@ void monitor_register_hmp_info_hrt(const char *name,
 static int get_monitor_def(MonitorHMP *hmp, int64_t *pval, const char *name)
 {
     CPUState *cs = monitor_hmp_get_cpu(hmp);
-    const MonitorDef *md;
+    const MonitorDef *md = NULL;
     void *ptr;
 
     if (cs == NULL) {
         return -1;
     }
+#ifdef CONFIG_HMP
     md = cs->cc->sysemu_ops->monitor_defs;
+#endif
     if (md == NULL) {
         return -1;
     }
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index f0687b5c482d..84e805ee85e2 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10853,6 +10853,7 @@ static const Property x86_cpu_properties[] = {
 
 #ifndef CONFIG_USER_ONLY
 
+#ifdef CONFIG_HMP
 static int64_t monitor_get_pc(MonitorHMP *hmp, const struct MonitorDef *md,
                               int offset)
 {
@@ -10878,6 +10879,7 @@ static const MonitorDef x86_monitor_defs[] = {
     { NULL },
 #undef SEG
 };
+#endif
 
 #include "hw/core/sysemu-cpu-ops.h"
 
@@ -10892,7 +10894,9 @@ static const struct SysemuCPUOps i386_sysemu_ops = {
     .write_elf64_note = x86_cpu_write_elf64_note,
     .write_elf32_qemunote = x86_cpu_write_elf32_qemunote,
     .write_elf64_qemunote = x86_cpu_write_elf64_qemunote,
+#ifdef CONFIG_HMP
     .monitor_defs = x86_monitor_defs,
+#endif
     .legacy_vmsd = &vmstate_x86_cpu,
 };
 #endif
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index ce2707dee5aa..aafcca3489b3 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -603,6 +603,7 @@ static const VMStateDescription vmstate_m68k_cpu = {
     },
 };
 
+#ifdef CONFIG_HMP
 static const MonitorDef m68k_monitor_defs[] = {
     { "ssp", offsetof(CPUM68KState, sp[0]) },
     { "usp", offsetof(CPUM68KState, sp[1]) },
@@ -618,13 +619,16 @@ static const MonitorDef m68k_monitor_defs[] = {
     { "mmusr", offsetof(CPUM68KState, mmu.mmusr) },
     { NULL },
 };
+#endif
 
 #include "hw/core/sysemu-cpu-ops.h"
 
 static const struct SysemuCPUOps m68k_sysemu_ops = {
     .has_work = m68k_cpu_has_work,
     .get_phys_addr_debug = m68k_cpu_get_phys_addr_debug,
+#ifdef CONFIG_HMP
     .monitor_defs = m68k_monitor_defs,
+#endif
 };
 #endif /* !CONFIG_USER_ONLY */
 
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 1bc14b586bb9..ae9bdca9df82 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -997,7 +997,7 @@ static const Property sparc_cpu_properties[] = {
 
 #ifdef TARGET_SPARC64
 #include "monitor/hmp.h"
-
+#ifdef CONFIG_HMP
 static const MonitorDef sparc64_monitor_defs[] = {
     { "asi", offsetof(CPUSPARCState, asi) },
     { "pstate", offsetof(CPUSPARCState, pstate) },
@@ -1009,6 +1009,7 @@ static const MonitorDef sparc64_monitor_defs[] = {
     { NULL },
 };
 #endif
+#endif
 
 #include "hw/core/sysemu-cpu-ops.h"
 
@@ -1016,7 +1017,7 @@ static const struct SysemuCPUOps sparc_sysemu_ops = {
     .has_work = sparc_cpu_has_work,
     .get_phys_addr_debug = sparc_cpu_get_phys_addr_debug,
     .legacy_vmsd = &vmstate_sparc_cpu,
-#if defined(TARGET_SPARC64)
+#if defined(TARGET_SPARC64) && defined(CONFIG_HMP)
     .monitor_defs = sparc64_monitor_defs,
 #endif
 };

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 43/49] hw: guard BusClass::print_dev with CONFIG_HMP
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (41 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 42/49] target: guard MonitorDef tables " Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-16 19:13 ` [PATCH v3 44/49] hexagon: condition HMP-specific code Marc-André Lureau
                   ` (5 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Laurent Vivier,
	Amit Shah, Michael S. Tsirkin, Paolo Bonzini, Stefano Stabellini,
	Anthony PERARD, Edgar E. Iglesias, xen-devel

The print_dev callback is only used by HMP 'info qtree'. Guard the field
in BusClass, all implementations, and the caller with CONFIG_HMP.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/char/virtio-serial-bus.c |  6 ++++++
 hw/core/sysbus.c            |  6 ++++++
 hw/misc/auxbus.c            | 16 +++++++++++-----
 hw/pci/pci-hmp-cmds.c       |  2 ++
 hw/pci/pci.c                |  2 ++
 hw/usb/bus.c                |  6 ++++++
 hw/xen/xen-bus.c            |  4 ++++
 include/hw/core/qdev.h      |  2 ++
 8 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 4dcc4516e45e..83a033ce8555 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -814,7 +814,9 @@ static int virtio_serial_load_device(VirtIODevice *vdev, QEMUFile *f,
     return 0;
 }
 
+#ifdef CONFIG_HMP
 static void virtser_bus_dev_print(MonitorHMP *hmp, DeviceState *qdev, int indent);
+#endif
 
 static const Property virtser_props[] = {
     DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID),
@@ -823,8 +825,10 @@ static const Property virtser_props[] = {
 
 static void virtser_bus_class_init(ObjectClass *klass, const void *data)
 {
+#ifdef CONFIG_HMP
     BusClass *k = BUS_CLASS(klass);
     k->print_dev = virtser_bus_dev_print;
+#endif
 }
 
 static const TypeInfo virtser_bus_info = {
@@ -834,6 +838,7 @@ static const TypeInfo virtser_bus_info = {
     .class_init = virtser_bus_class_init,
 };
 
+#ifdef CONFIG_HMP
 static void virtser_bus_dev_print(MonitorHMP *hmp, DeviceState *qdev, int indent)
 {
     VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(qdev);
@@ -844,6 +849,7 @@ static void virtser_bus_dev_print(MonitorHMP *hmp, DeviceState *qdev, int indent
                        port->host_connected ? "on" : "off",
                        port->throttled ? "on" : "off");
 }
+#endif
 
 /* This function is only used if a port id is not provided by the user */
 static uint32_t find_free_port_id(VirtIOSerial *vser)
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 31c4fdf79d48..fe8f867a8d9c 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -24,7 +24,9 @@
 #include "monitor/hmp.h"
 #include "system/address-spaces.h"
 
+#ifdef CONFIG_HMP
 static void sysbus_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent);
+#endif
 static char *sysbus_get_fw_dev_path(DeviceState *dev);
 
 typedef struct SysBusFind {
@@ -76,7 +78,9 @@ static void system_bus_class_init(ObjectClass *klass, const void *data)
 {
     BusClass *k = BUS_CLASS(klass);
 
+#ifdef CONFIG_HMP
     k->print_dev = sysbus_dev_print;
+#endif
     k->get_fw_dev_path = sysbus_get_fw_dev_path;
 }
 
@@ -249,6 +253,7 @@ bool sysbus_realize_and_unref(SysBusDevice *dev, Error **errp)
     return qdev_realize_and_unref(DEVICE(dev), sysbus_get_default(), errp);
 }
 
+#ifdef CONFIG_HMP
 static void sysbus_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent)
 {
     SysBusDevice *s = SYS_BUS_DEVICE(dev);
@@ -261,6 +266,7 @@ static void sysbus_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent)
                            indent, "", s->mmio[i].addr, size);
     }
 }
+#endif
 
 static char *sysbus_get_fw_dev_path(DeviceState *dev)
 {
diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
index 0bb89c5a60ab..3f17784d9b8a 100644
--- a/hw/misc/auxbus.c
+++ b/hw/misc/auxbus.c
@@ -47,18 +47,22 @@
 } while (0)
 
 
+#ifdef CONFIG_HMP
 static void aux_slave_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent);
+#endif
 static inline I2CBus *aux_bridge_get_i2c_bus(AUXTOI2CState *bridge);
 
 /* aux-bus implementation (internal not public) */
 static void aux_bus_class_init(ObjectClass *klass, const void *data)
 {
+#ifdef CONFIG_HMP
     BusClass *k = BUS_CLASS(klass);
 
     /* AUXSlave has an MMIO so we need to change the way we print information
      * in monitor.
      */
     k->print_dev = aux_slave_dev_print;
+#endif
 }
 
 AUXBus *aux_bus_init(DeviceState *parent, const char *name)
@@ -91,11 +95,6 @@ void aux_map_slave(AUXSlave *aux_dev, hwaddr addr)
     memory_region_add_subregion(bus->aux_io, addr, aux_dev->mmio);
 }
 
-static bool aux_bus_is_bridge(AUXBus *bus, DeviceState *dev)
-{
-    return (dev == DEVICE(bus->bridge));
-}
-
 I2CBus *aux_get_i2c_bus(AUXBus *bus)
 {
     return aux_bridge_get_i2c_bus(bus->bridge);
@@ -288,6 +287,12 @@ static const TypeInfo aux_to_i2c_type_info = {
 };
 
 /* aux-slave implementation */
+#ifdef CONFIG_HMP
+static bool aux_bus_is_bridge(AUXBus *bus, DeviceState *dev)
+{
+    return (dev == DEVICE(bus->bridge));
+}
+
 static void aux_slave_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent)
 {
     AUXBus *bus = AUX_BUS(qdev_get_parent_bus(dev));
@@ -305,6 +310,7 @@ static void aux_slave_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent)
                        object_property_get_uint(OBJECT(s->mmio), "addr", NULL),
                        memory_region_size(s->mmio));
 }
+#endif
 
 void aux_init_mmio(AUXSlave *aux_slave, MemoryRegion *mmio)
 {
diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c
index bcccfaf07f4d..879011da1384 100644
--- a/hw/pci/pci-hmp-cmds.c
+++ b/hw/pci/pci-hmp-cmds.c
@@ -135,6 +135,7 @@ void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict)
     qapi_free_PciInfoList(info_list);
 }
 
+#ifdef CONFIG_HMP
 void pcibus_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent)
 {
     PCIDevice *d = (PCIDevice *)dev;
@@ -170,6 +171,7 @@ void pcibus_dev_print(MonitorHMP *hmp, DeviceState *dev, int indent)
                            r->addr, r->addr + r->size - 1);
     }
 }
+#endif
 
 void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict)
 {
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index d3191609e283..9e5db9529379 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -290,7 +290,9 @@ static void pci_bus_class_init(ObjectClass *klass, const void *data)
     ResettableClass *rc = RESETTABLE_CLASS(klass);
     FWCfgDataGeneratorClass *fwgc = FW_CFG_DATA_GENERATOR_CLASS(klass);
 
+#ifdef CONFIG_HMP
     k->print_dev = pcibus_dev_print;
+#endif
     k->get_dev_path = pcibus_get_dev_path;
     k->get_fw_dev_path = pcibus_get_fw_dev_path;
     k->realize = pci_bus_realize;
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 8bd25a9d872a..5cc5ffec33a1 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -13,7 +13,9 @@
 #include "trace.h"
 #include "qemu/cutils.h"
 
+#ifdef CONFIG_HMP
 static void usb_bus_dev_print(MonitorHMP *hmp, DeviceState *qdev, int indent);
+#endif
 
 static char *usb_get_dev_path(DeviceState *dev);
 static char *usb_get_fw_dev_path(DeviceState *qdev);
@@ -32,7 +34,9 @@ static void usb_bus_class_init(ObjectClass *klass, const void *data)
     BusClass *k = BUS_CLASS(klass);
     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
 
+#ifdef CONFIG_HMP
     k->print_dev = usb_bus_dev_print;
+#endif
     k->get_dev_path = usb_get_dev_path;
     k->get_fw_dev_path = usb_get_fw_dev_path;
     hc->unplug = qdev_simple_device_unplug_cb;
@@ -544,6 +548,7 @@ static const char *usb_speed(unsigned int speed)
     return txt[speed];
 }
 
+#ifdef CONFIG_HMP
 static void usb_bus_dev_print(MonitorHMP *hmp, DeviceState *qdev, int indent)
 {
     USBDevice *dev = USB_DEVICE(qdev);
@@ -555,6 +560,7 @@ static void usb_bus_dev_print(MonitorHMP *hmp, DeviceState *qdev, int indent)
                        usb_speed(dev->speed), dev->product_desc,
                        dev->attached ? ", attached" : "");
 }
+#endif
 
 static char *usb_get_dev_path(DeviceState *qdev)
 {
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index b81a067e7753..1762816bf469 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -101,6 +101,7 @@ abort:
     qemu_xen_xs_transaction_end(xenbus->xsh, tid, true);
 }
 
+#ifdef CONFIG_HMP
 static void xen_bus_print_dev(MonitorHMP *hmp, DeviceState *dev, int indent)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
@@ -108,6 +109,7 @@ static void xen_bus_print_dev(MonitorHMP *hmp, DeviceState *dev, int indent)
     monitor_hmp_printf(hmp, "%*sname = '%s' frontend_id = %u\n",
                        indent, "", xendev->name, xendev->frontend_id);
 }
+#endif
 
 static char *xen_bus_get_dev_path(DeviceState *dev)
 {
@@ -386,7 +388,9 @@ static void xen_bus_class_init(ObjectClass *class, const void *data)
     BusClass *bus_class = BUS_CLASS(class);
     HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class);
 
+#ifdef CONFIG_HMP
     bus_class->print_dev = xen_bus_print_dev;
+#endif
     bus_class->get_dev_path = xen_bus_get_dev_path;
     bus_class->realize = xen_bus_realize;
     bus_class->unrealize = xen_bus_unrealize;
diff --git a/include/hw/core/qdev.h b/include/hw/core/qdev.h
index 1391dc060caf..f054a214fc6a 100644
--- a/include/hw/core/qdev.h
+++ b/include/hw/core/qdev.h
@@ -323,8 +323,10 @@ DECLARE_OBJ_CHECKERS(BusState, BusClass,
 struct BusClass {
     ObjectClass parent_class;
 
+#ifdef CONFIG_HMP
     /* FIXME first arg should be BusState */
     void (*print_dev)(MonitorHMP *mon, DeviceState *dev, int indent);
+#endif
     /*
      * Return a newly allocated string containing the path of the
      * device on this bus.

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 44/49] hexagon: condition HMP-specific code
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (42 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 43/49] hw: guard BusClass::print_dev " Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-17  3:46   ` Philippe Mathieu-Daudé
  2026-08-16 19:13 ` [PATCH v3 45/49] build-sys: make HMP source files conditional on have_hmp Marc-André Lureau
                   ` (4 subsequent siblings)
  48 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Brian Cain,
	Pierrick Bouvier

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/hexagon/hexagon_tlb.c | 42 ++++++++++++++++++++++--------------------
 target/hexagon/hex_mmu.c |  2 ++
 2 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/hw/hexagon/hexagon_tlb.c b/hw/hexagon/hexagon_tlb.c
index 584c606a22c5..ed8c0a761228 100644
--- a/hw/hexagon/hexagon_tlb.c
+++ b/hw/hexagon/hexagon_tlb.c
@@ -57,19 +57,6 @@ typedef enum {
 
 #define NUM_PGSIZE_TYPES (PGSIZE_1G + 1)
 
-static const char *pgsize_str[NUM_PGSIZE_TYPES] = {
-    "4K",
-    "16K",
-    "64K",
-    "256K",
-    "1M",
-    "4M",
-    "16M",
-    "64M",
-    "256M",
-    "1G",
-};
-
 #define INVALID_MASK 0xffffffffLL
 
 static const uint64_t encmask_2_mask[] = {
@@ -122,6 +109,20 @@ static inline uint64_t hex_tlb_virt_addr(uint64_t entry)
     return (uint64_t)GET_PTE_VPN(entry) << qemu_target_page_bits();
 }
 
+#ifdef CONFIG_HMP
+static const char *pgsize_str[NUM_PGSIZE_TYPES] = {
+    "4K",
+    "16K",
+    "64K",
+    "256K",
+    "1M",
+    "4M",
+    "16M",
+    "64M",
+    "256M",
+    "1G",
+};
+
 bool hexagon_tlb_dump_entry(MonitorHMP *hmp, uint64_t entry)
 {
     if (GET_PTE_V(entry)) {
@@ -155,6 +156,14 @@ bool hexagon_tlb_dump_entry(MonitorHMP *hmp, uint64_t entry)
     return false;
 }
 
+void hexagon_tlb_dump(MonitorHMP *hmp, HexagonTLBState *tlb)
+{
+    for (uint32_t i = 0; i < tlb->num_entries; i++) {
+        hexagon_tlb_dump_entry(hmp, tlb->entries[i]);
+    }
+}
+#endif
+
 static inline bool hex_tlb_entry_match_noperm(uint64_t entry, uint32_t asid,
                                               uint64_t VA)
 {
@@ -377,13 +386,6 @@ int hexagon_tlb_check_overlap(HexagonTLBState *tlb, uint64_t entry,
     return -1;
 }
 
-void hexagon_tlb_dump(MonitorHMP *hmp, HexagonTLBState *tlb)
-{
-    for (uint32_t i = 0; i < tlb->num_entries; i++) {
-        hexagon_tlb_dump_entry(hmp, tlb->entries[i]);
-    }
-}
-
 uint32_t hexagon_tlb_get_num_entries(HexagonTLBState *tlb)
 {
     return tlb->num_entries;
diff --git a/target/hexagon/hex_mmu.c b/target/hexagon/hex_mmu.c
index 242de06eaad2..12bcddd000bf 100644
--- a/target/hexagon/hex_mmu.c
+++ b/target/hexagon/hex_mmu.c
@@ -107,11 +107,13 @@ int hex_tlb_check_overlap(CPUHexagonState *env, uint64_t entry, uint64_t index)
     return hexagon_tlb_check_overlap(cpu->tlb, entry, index);
 }
 
+#ifdef CONFIG_HMP
 void dump_mmu(MonitorHMP *hmp, CPUHexagonState *env)
 {
     HexagonCPU *cpu = env_archcpu(env);
     hexagon_tlb_dump(hmp, cpu->tlb);
 }
+#endif
 
 static inline void print_thread(const char *str, CPUState *cs)
 {

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 45/49] build-sys: make HMP source files conditional on have_hmp
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (43 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 44/49] hexagon: condition HMP-specific code Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-16 19:13 ` [PATCH v3 46/49] stubs: split monitor-core stubs into separate compilation units Marc-André Lureau
                   ` (3 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Gerd Hoffmann,
	Kevin Wolf, Hanna Reitz, Paolo Bonzini, Ani Sinha,
	Michael S. Tsirkin, Richard Henderson, Jason Wang,
	Pierrick Bouvier, Peter Xu, Fabiano Rosas, Dr. David Alan Gilbert,
	Laurent Vivier, Stefan Hajnoczi, qemu-block

Exclude all *-hmp-cmds.c files and HMP-only source files from the
build when HMP is disabled.

Also conditionalise the hmp-commands.hx header generation and the
test-hmp qtest.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 audio/meson.build         |  4 +++-
 backends/meson.build      |  5 ++++-
 block/monitor/meson.build |  4 +++-
 chardev/meson.build       |  5 ++++-
 disas/meson.build         |  4 +++-
 dump/meson.build          |  5 ++++-
 hw/core/meson.build       |  5 +++--
 hw/i386/meson.build       |  4 +++-
 hw/net/meson.build        |  4 +++-
 hw/pci/meson.build        |  4 +++-
 hw/virtio/meson.build     |  4 +++-
 meson.build               |  2 +-
 migration/meson.build     |  4 +++-
 monitor/hmp.c             |  2 --
 monitor/meson.build       |  9 +++++++--
 net/meson.build           |  4 +++-
 qom/meson.build           |  4 +++-
 stats/meson.build         |  5 ++++-
 stubs/meson.build         | 12 +++++++-----
 system/meson.build        | 11 ++++++++---
 tests/qtest/meson.build   |  8 +++++++-
 trace/meson.build         |  5 ++++-
 ui/meson.build            |  4 +++-
 23 files changed, 86 insertions(+), 32 deletions(-)

diff --git a/audio/meson.build b/audio/meson.build
index 0e33b6f9836e..6655f601b115 100644
--- a/audio/meson.build
+++ b/audio/meson.build
@@ -9,7 +9,9 @@ audio_ss.add(files(
 ))
 
 # deprecated since v10.2, to be removed
-system_ss.add(files('audio-hmp-cmds.c', 'wavcapture.c'))
+if have_hmp
+  system_ss.add(files('audio-hmp-cmds.c', 'wavcapture.c'))
+endif
 
 audio_modules = {}
 foreach m : [
diff --git a/backends/meson.build b/backends/meson.build
index 8792c58c361f..224e96753527 100644
--- a/backends/meson.build
+++ b/backends/meson.build
@@ -1,6 +1,5 @@
 system_ss.add([files(
   'cryptodev-builtin.c',
-  'cryptodev-hmp-cmds.c',
   'cryptodev.c',
   'hostmem-ram.c',
   'hostmem.c',
@@ -10,6 +9,10 @@ system_ss.add([files(
   'confidential-guest-support.c',
 ), numa])
 
+if have_hmp
+  system_ss.add(files('cryptodev-hmp-cmds.c'))
+endif
+
 if host_os != 'windows'
   system_ss.add(files('rng-random.c'))
   if host_os != 'emscripten'
diff --git a/block/monitor/meson.build b/block/monitor/meson.build
index 74faced9e17f..2d5c157a7391 100644
--- a/block/monitor/meson.build
+++ b/block/monitor/meson.build
@@ -1,3 +1,5 @@
-system_ss.add(files('block-hmp-cmds.c'))
+if have_hmp
+  system_ss.add(files('block-hmp-cmds.c'))
+endif
 block_ss.add(files('bitmap-qmp-cmds.c'))
 system_ss.add(files('qmp-cmds.c'))
diff --git a/chardev/meson.build b/chardev/meson.build
index 56ee39ac0b01..031b6d7238c1 100644
--- a/chardev/meson.build
+++ b/chardev/meson.build
@@ -30,11 +30,14 @@ endif
 chardev_ss = chardev_ss.apply({})
 
 system_ss.add(files(
-    'char-hmp-cmds.c',
     'msmouse.c',
     'wctablet.c',
     'testdev.c'))
 
+if have_hmp
+    system_ss.add(files('char-hmp-cmds.c'))
+endif
+
 chardev_modules = {}
 
 if brlapi.found()
diff --git a/disas/meson.build b/disas/meson.build
index 42977a1f74dd..b382550e41f8 100644
--- a/disas/meson.build
+++ b/disas/meson.build
@@ -20,5 +20,7 @@ common_ss.add(when: 'CONFIG_TCG', if_true: files(
     'objdump.c'
 ))
 common_ss.add(files('disas-common.c'))
-system_ss.add(files('disas-mon.c'))
+if have_hmp
+  system_ss.add(files('disas-mon.c'))
+endif
 specific_ss.add(capstone)
diff --git a/dump/meson.build b/dump/meson.build
index 26e1561ed486..bef8276aa5ad 100644
--- a/dump/meson.build
+++ b/dump/meson.build
@@ -1,3 +1,6 @@
-system_ss.add([files('dump.c', 'dump-hmp-cmds.c'), snappy, lzo])
+system_ss.add([files('dump.c'), snappy, lzo])
+if have_hmp
+  system_ss.add(files('dump-hmp-cmds.c'))
+endif
 specific_ss.add(when: 'CONFIG_WINDUMP', if_true: files('win_dump-x86.c'))
 system_ss.add(when: 'CONFIG_WINDUMP', if_false: files('win_dump-stubs.c'))
diff --git a/hw/core/meson.build b/hw/core/meson.build
index 8a96567de8f2..8fe776d2c86b 100644
--- a/hw/core/meson.build
+++ b/hw/core/meson.build
@@ -26,13 +26,11 @@ system_ss.add(when: 'CONFIG_SPLIT_IRQ', if_true: files('split-irq.c'))
 system_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('stream.c'))
 system_ss.add(when: 'CONFIG_PLATFORM_BUS', if_true: files('sysbus-fdt.c'))
 system_ss.add(when: 'CONFIG_EIF', if_true: [files('eif.c'), zlib, libcbor, gnutls])
-
 system_ss.add(files(
   'cpu-system.c',
   'fw-path-provider.c',
   'hotplug.c',
   'loader.c',
-  'machine-hmp-cmds.c',
   'machine-qmp-cmds.c',
   'machine.c',
   'nmi.c',
@@ -46,6 +44,9 @@ system_ss.add(files(
   'vm-change-state-handler.c',
   'clock-vmstate.c',
 ))
+if have_hmp
+  system_ss.add(files('machine-hmp-cmds.c'))
+endif
 user_ss.add(files(
   'cpu-user.c',
   'qdev-user.c',
diff --git a/hw/i386/meson.build b/hw/i386/meson.build
index b611fbb5a7fb..125f4ce894ca 100644
--- a/hw/i386/meson.build
+++ b/hw/i386/meson.build
@@ -24,7 +24,9 @@ i386_ss.add(when: 'CONFIG_VTD', if_true: files('intel_iommu.c'))
 i386_ss.add(when: 'CONFIG_VTD_ACCEL', if_true: files('intel_iommu_accel.c'))
 i386_ss.add(when: 'CONFIG_SGX', if_true: files('sgx-epc.c','sgx.c'),
                                 if_false: files('sgx-stub.c'))
-stub_ss.add(files('sgx-hmp-stub.c'))
+if have_hmp
+  stub_ss.add(files('sgx-hmp-stub.c'))
+endif
 
 i386_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-common.c'))
 i386_ss.add(when: 'CONFIG_PC', if_true: files(
diff --git a/hw/net/meson.build b/hw/net/meson.build
index 84f142df222a..df3373be03bf 100644
--- a/hw/net/meson.build
+++ b/hw/net/meson.build
@@ -67,6 +67,8 @@ system_ss.add(when: 'CONFIG_ROCKER', if_true: files(
   'rocker/rocker_world.c',
 ))
 stub_ss.add(files('rocker/rocker-stubs.c'))
-system_ss.add(files('rocker/rocker-hmp-cmds.c'))
+if have_hmp
+  system_ss.add(files('rocker/rocker-hmp-cmds.c'))
+endif
 
 subdir('can')
diff --git a/hw/pci/meson.build b/hw/pci/meson.build
index a6cbd89c0a38..984c7327e5d0 100644
--- a/hw/pci/meson.build
+++ b/hw/pci/meson.build
@@ -5,12 +5,14 @@ pci_ss.add(files(
   'pci.c',
   'pci_bridge.c',
   'pci_host.c',
-  'pci-hmp-cmds.c',
   'pci-qmp-cmds.c',
   'pcie_sriov.c',
   'shpc.c',
   'slotid_cap.c'
 ))
+if have_hmp
+  pci_ss.add(files('pci-hmp-cmds.c'))
+endif
 # The functions in these modules can be used by devices too.  Since we
 # allow plugging PCIe devices into PCI buses, include them even if
 # CONFIG_PCI_EXPRESS=n.
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index 0e023235164b..b59f455a5114 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -100,6 +100,8 @@ stub_ss.add(files('vhost-user-stub.c'))
 stub_ss.add(files('virtio-stub.c'))
 stub_ss.add(files('virtio-md-stubs.c'))
 
-system_ss.add(files('virtio-hmp-cmds.c'))
+if have_hmp
+  system_ss.add(files('virtio-hmp-cmds.c'))
+endif
 
 system_ss.add(when: 'CONFIG_ACPI', if_true: files('virtio-acpi.c'))
diff --git a/meson.build b/meson.build
index 03b334549f23..8ac35151604b 100644
--- a/meson.build
+++ b/meson.build
@@ -3549,7 +3549,7 @@ hx_headers = [
   ['qemu-options.hx', 'qemu-options.def'],
   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
 ]
-if have_system
+if have_system and have_hmp
   hx_headers += [
     ['hmp-commands.hx', 'hmp-commands.h'],
     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
diff --git a/migration/meson.build b/migration/meson.build
index 0a9a5d0d3746..4ab9d99cea62 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -36,7 +36,9 @@ system_ss.add(files(
   'socket.c',
   'tls.c',
 ), gnutls, zlib)
-system_ss.add([spice_headers, files('migration-hmp-cmds.c'), spice])
+if have_hmp
+  system_ss.add([spice_headers, files('migration-hmp-cmds.c'), spice])
+endif
 
 if get_option('replication').allowed()
   system_ss.add(files('colo-failover.c', 'colo.c', 'multifd-colo.c'))
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 3c70adcd35bb..10bcbe2a33cb 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -1731,9 +1731,7 @@ static int get_monitor_def(MonitorHMP *hmp, int64_t *pval, const char *name)
     if (cs == NULL) {
         return -1;
     }
-#ifdef CONFIG_HMP
     md = cs->cc->sysemu_ops->monitor_defs;
-#endif
     if (md == NULL) {
         return -1;
     }
diff --git a/monitor/meson.build b/monitor/meson.build
index 4c58dd148c04..f67e0291a42a 100644
--- a/monitor/meson.build
+++ b/monitor/meson.build
@@ -2,8 +2,13 @@ qmp_ss.add(files('monitor.c', 'qmp.c', 'qmp-cmds-control.c'))
 
 system_ss.add(files(
   'fds.c',
-  'hmp-cmds.c',
-  'hmp.c',
   'qemu-config-qmp.c',
   'qmp-cmds.c',
 ))
+
+if have_hmp
+  system_ss.add(files(
+    'hmp-cmds.c',
+    'hmp.c',
+  ))
+endif
diff --git a/net/meson.build b/net/meson.build
index 9c8068b06d1f..5bb76d136491 100644
--- a/net/meson.build
+++ b/net/meson.build
@@ -8,7 +8,6 @@ system_ss.add(files(
   'filter-mirror.c',
   'filter.c',
   'hub.c',
-  'net-hmp-cmds.c',
   'net.c',
   'queue.c',
   'socket.c',
@@ -16,6 +15,9 @@ system_ss.add(files(
   'stream_data.c',
   'util.c',
 ))
+if have_hmp
+  system_ss.add(files('net-hmp-cmds.c'))
+endif
 
 if get_option('replication').allowed() or \
     get_option('colo_proxy').allowed()
diff --git a/qom/meson.build b/qom/meson.build
index bd6f4aadd78a..022d3ad5c8f1 100644
--- a/qom/meson.build
+++ b/qom/meson.build
@@ -10,4 +10,6 @@ if have_system
 endif
 
 qmp_ss.add(files('qom-qmp-cmds.c'))
-system_ss.add(files('qom-hmp-cmds.c'))
+if have_hmp
+  system_ss.add(files('qom-hmp-cmds.c'))
+endif
diff --git a/stats/meson.build b/stats/meson.build
index 0728dafcd1c7..b5f68a94052e 100644
--- a/stats/meson.build
+++ b/stats/meson.build
@@ -1 +1,4 @@
-system_ss.add(files('stats-hmp-cmds.c', 'stats-qmp-cmds.c'))
+system_ss.add(files('stats-qmp-cmds.c'))
+if have_hmp
+  system_ss.add(files('stats-hmp-cmds.c'))
+endif
diff --git a/stubs/meson.build b/stubs/meson.build
index 7e15687a62b7..93df8ea94f57 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -86,11 +86,13 @@ if have_system
   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'))
-  stub_ss.add(files('hmp-cmd-info_sev.c'))
-  stub_ss.add(files('hmp-cmd-info_tlb.c'))
-  stub_ss.add(files('hmp-cmds-hw-s390x.c'))
-  stub_ss.add(files('hmp-cmds-target-i386.c'))
+  if have_hmp
+    stub_ss.add(files('hmp-cmd-info_mem.c'))
+    stub_ss.add(files('hmp-cmd-info_sev.c'))
+    stub_ss.add(files('hmp-cmd-info_tlb.c'))
+    stub_ss.add(files('hmp-cmds-hw-s390x.c'))
+    stub_ss.add(files('hmp-cmds-target-i386.c'))
+  endif
 endif
 
 if have_system or have_user
diff --git a/system/meson.build b/system/meson.build
index 64e06e7abcc3..41e2e4a292d1 100644
--- a/system/meson.build
+++ b/system/meson.build
@@ -9,7 +9,6 @@ system_ss.add(files(
   'cpus.c',
   'cpu-timers.c',
   'dirtylimit.c',
-  'dirtylimit-hmp-cmds.c',
   'dma-helpers.c',
   'exit-with-parent.c',
   'globals.c',
@@ -24,12 +23,18 @@ system_ss.add(files(
   'qtest.c',
   'rtc.c',
   'runstate-action.c',
-  'runstate-hmp-cmds.c',
   'runstate.c',
-  'tpm-hmp-cmds.c',
   'watchpoint.c',
 ))
 
+if have_hmp
+  system_ss.add(files(
+    'dirtylimit-hmp-cmds.c',
+    'runstate-hmp-cmds.c',
+    'tpm-hmp-cmds.c',
+  ))
+endif
+
 if have_tpm
   system_ss.add(files('tpm.c'))
 endif
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index f7c7d06620ea..4cf4407c2bd0 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -26,7 +26,13 @@ qtests_generic = [
   'qmp-test',
   'qmp-cmd-test',
   'qom-test',
-  'test-hmp',
+]
+if have_hmp
+  qtests_generic += [
+    'test-hmp',
+  ]
+endif
+qtests_generic += [
   'qos-test',
   'readconfig-test',
   'netdev-socket',
diff --git a/trace/meson.build b/trace/meson.build
index d89a0db82a14..4e5681c44cae 100644
--- a/trace/meson.build
+++ b/trace/meson.build
@@ -1,4 +1,7 @@
-system_ss.add(files('control-target.c', 'trace-hmp-cmds.c'))
+system_ss.add(files('control-target.c'))
+if have_hmp
+  system_ss.add(files('trace-hmp-cmds.c'))
+endif
 trace_rs_targets = []
 trace_events_files = []
 foreach item : [ '.' ] + trace_events_subdirs + qapi_trace_events
diff --git a/ui/meson.build b/ui/meson.build
index d345f6c70d6a..39829a2c6e23 100644
--- a/ui/meson.build
+++ b/ui/meson.build
@@ -56,10 +56,12 @@ system_ss.add(png)
 system_ss.add(files(
   'input-barrier.c',
   'input.c',
-  'ui-hmp-cmds.c',
   'ui-qmp-cmds.c',
   'util.c',
 ))
+if have_hmp
+  system_ss.add(files('ui-hmp-cmds.c'))
+endif
 system_ss.add(ui)
 system_ss.add(when: pixman, if_true: files('console-vc.c'), if_false: files('console-vc-stubs.c'))
 if dbus_display

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 46/49] stubs: split monitor-core stubs into separate compilation units
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (44 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 45/49] build-sys: make HMP source files conditional on have_hmp Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-16 19:13 ` [PATCH v3 47/49] monitor: move monitor_hmp_print*() functions to hmp.c Marc-André Lureau
                   ` (2 subsequent siblings)
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Paolo Bonzini

The wild linker rejects duplicate symbols even from archive members.
When qemu-storage-daemon links both libqmp (with monitor/monitor.c)
and libqemuutil (with stubs/monitor-core.c), all symbols from the
stub .o are pulled in, causing duplicates for monitor_cur,
monitor_set_cur, and qapi_event_emit.

Split each stub group into its own file so the linker only pulls in
archive members whose symbols are actually needed.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 stubs/meson.build       |  2 ++
 stubs/monitor-core.c    | 16 ----------------
 stubs/monitor-cur.c     | 14 ++++++++++++++
 stubs/qapi-event-emit.c |  8 ++++++++
 4 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/stubs/meson.build b/stubs/meson.build
index 93df8ea94f57..29b6644b2549 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -7,7 +7,9 @@ stub_ss.add(files('fdset.c'))
 stub_ss.add(files('iothread-lock.c'))
 stub_ss.add(files('is-daemonized.c'))
 stub_ss.add(files('monitor-core.c'))
+stub_ss.add(files('monitor-cur.c'))
 stub_ss.add(files('monitor-hmp.c'))
+stub_ss.add(files('qapi-event-emit.c'))
 stub_ss.add(files('replay-mode.c'))
 stub_ss.add(files('trace-control.c'))
 
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
index 094b80721003..0e74d78d52e4 100644
--- a/stubs/monitor-core.c
+++ b/stubs/monitor-core.c
@@ -1,21 +1,5 @@
 #include "qemu/osdep.h"
-#include "monitor/monitor.h"
 #include "monitor/hmp.h"
-#include "qapi/qapi-emit-events.h"
-
-Monitor *monitor_cur(void)
-{
-    return NULL;
-}
-
-Monitor *monitor_set_cur(Coroutine *co, Monitor *mon)
-{
-    return NULL;
-}
-
-void qapi_event_emit(QAPIEvent event, QDict *qdict)
-{
-}
 
 int monitor_hmp_vprintf(MonitorHMP *mon, const char *fmt, va_list ap)
 {
diff --git a/stubs/monitor-cur.c b/stubs/monitor-cur.c
new file mode 100644
index 000000000000..93966a16b855
--- /dev/null
+++ b/stubs/monitor-cur.c
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "monitor/monitor.h"
+
+Monitor *monitor_cur(void)
+{
+    return NULL;
+}
+
+Monitor *monitor_set_cur(Coroutine *co, Monitor *mon)
+{
+    return NULL;
+}
diff --git a/stubs/qapi-event-emit.c b/stubs/qapi-event-emit.c
new file mode 100644
index 000000000000..70b2719d714b
--- /dev/null
+++ b/stubs/qapi-event-emit.c
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qapi/qapi-emit-events.h"
+
+void qapi_event_emit(QAPIEvent event, QDict *qdict)
+{
+}

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 47/49] monitor: move monitor_hmp_print*() functions to hmp.c
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (45 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 46/49] stubs: split monitor-core stubs into separate compilation units Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-16 19:13 ` [PATCH v3 48/49] monitor: move HMP-specific to monitor-hmp-internal.h Marc-André Lureau
  2026-08-16 19:13 ` [PATCH v3 49/49] gitlab: --disable-hmp in build-without-defaults Marc-André Lureau
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Dr. David Alan Gilbert

Those functions are only used when CONFIG_HMP, compile them out, and add
conditions for the calling code.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

# The commit message #2 will be skipped:

# fixup! monitor: move monitor_hmp_print*() functions to hmp.c
---
 monitor/hmp.c       | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 monitor/monitor.c   | 49 -------------------------------------------------
 util/error-report.c |  3 ++-
 util/qemu-print.c   |  4 ++++
 4 files changed, 55 insertions(+), 50 deletions(-)

diff --git a/monitor/hmp.c b/monitor/hmp.c
index 10bcbe2a33cb..e3fc05f521a8 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -1754,3 +1754,52 @@ static int get_monitor_def(MonitorHMP *hmp, int64_t *pval, const char *name)
     }
     return cs->cc->sysemu_ops->monitor_get_register(cs, name, pval);
 }
+
+int monitor_hmp_vprintf(MonitorHMP *hmp, const char *fmt, va_list ap)
+{
+    g_autofree char *buf = g_strdup_vprintf(fmt, ap);
+
+    if (!hmp) {
+        return -1;
+    }
+
+    return monitor_puts(MONITOR(hmp), buf);
+}
+
+int monitor_hmp_printf(MonitorHMP *hmp, const char *fmt, ...)
+{
+    int ret;
+
+    va_list ap;
+    va_start(ap, fmt);
+    ret = monitor_hmp_vprintf(hmp, fmt, ap);
+    va_end(ap);
+    return ret;
+}
+
+void monitor_hmp_printc(MonitorHMP *hmp, int c)
+{
+    monitor_hmp_printf(hmp, "'");
+    switch (c) {
+    case '\'':
+        monitor_hmp_printf(hmp, "\\'");
+        break;
+    case '\\':
+        monitor_hmp_printf(hmp, "\\\\");
+        break;
+    case '\n':
+        monitor_hmp_printf(hmp, "\\n");
+        break;
+    case '\r':
+        monitor_hmp_printf(hmp, "\\r");
+        break;
+    default:
+        if (c >= 32 && c <= 126) {
+            monitor_hmp_printf(hmp, "%c", c);
+        } else {
+            monitor_hmp_printf(hmp, "\\x%02x", c);
+        }
+        break;
+    }
+    monitor_hmp_printf(hmp, "'");
+}
diff --git a/monitor/monitor.c b/monitor/monitor.c
index da0c8eda86b0..7979cd1cbcfd 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -272,55 +272,6 @@ int monitor_puts(Monitor *mon, const char *str)
     return monitor_puts_locked(mon, str);
 }
 
-int monitor_hmp_vprintf(MonitorHMP *mon, const char *fmt, va_list ap)
-{
-    g_autofree char *buf = g_strdup_vprintf(fmt, ap);
-
-    if (!mon) {
-        return -1;
-    }
-
-    return monitor_puts(MONITOR(mon), buf);
-}
-
-int monitor_hmp_printf(MonitorHMP *mon, const char *fmt, ...)
-{
-    int ret;
-
-    va_list ap;
-    va_start(ap, fmt);
-    ret = monitor_hmp_vprintf(mon, fmt, ap);
-    va_end(ap);
-    return ret;
-}
-
-void monitor_hmp_printc(MonitorHMP *mon, int c)
-{
-    monitor_hmp_printf(mon, "'");
-    switch(c) {
-    case '\'':
-        monitor_hmp_printf(mon, "\\'");
-        break;
-    case '\\':
-        monitor_hmp_printf(mon, "\\\\");
-        break;
-    case '\n':
-        monitor_hmp_printf(mon, "\\n");
-        break;
-    case '\r':
-        monitor_hmp_printf(mon, "\\r");
-        break;
-    default:
-        if (c >= 32 && c <= 126) {
-            monitor_hmp_printf(mon, "%c", c);
-        } else {
-            monitor_hmp_printf(mon, "\\x%02x", c);
-        }
-        break;
-    }
-    monitor_hmp_printf(mon, "'");
-}
-
 static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
     /* Limit guest-triggerable events to 1 per second */
     [QAPI_EVENT_RTC_CHANGE]        = { 1000 * SCALE_MS },
diff --git a/util/error-report.c b/util/error-report.c
index c20e157780fa..68471d8055a1 100644
--- a/util/error-report.c
+++ b/util/error-report.c
@@ -35,12 +35,13 @@ const char *error_guest_name;
 static int G_GNUC_PRINTF(1, 0)
 error_vprintf_mon(const char *fmt, va_list ap)
 {
+#ifdef CONFIG_HMP
     MonitorHMP *hmp = monitor_cur_hmp();
 
     if (hmp) {
         return monitor_hmp_vprintf(hmp, fmt, ap);
     }
-
+#endif
     return vfprintf(stderr, fmt, ap);
 }
 
diff --git a/util/qemu-print.c b/util/qemu-print.c
index aabe670fda01..f4a7ce4c0682 100644
--- a/util/qemu-print.c
+++ b/util/qemu-print.c
@@ -21,10 +21,12 @@
  */
 int qemu_vprintf(const char *fmt, va_list ap)
 {
+#ifdef CONFIG_HMP
     MonitorHMP *hmp = monitor_cur_hmp();
     if (hmp) {
         return monitor_hmp_vprintf(hmp, fmt, ap);
     }
+#endif
     return vprintf(fmt, ap);
 }
 
@@ -52,10 +54,12 @@ int qemu_printf(const char *fmt, ...)
  */
 int qemu_vfprintf(FILE *stream, const char *fmt, va_list ap)
 {
+#ifdef CONFIG_HMP
     if (!stream) {
         MonitorHMP *hmp = monitor_cur_hmp();
         return hmp ? monitor_hmp_vprintf(hmp, fmt, ap) : -1;
     }
+#endif
     return vfprintf(stream, fmt, ap);
 }
 

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 48/49] monitor: move HMP-specific to monitor-hmp-internal.h
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (46 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 47/49] monitor: move monitor_hmp_print*() functions to hmp.c Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  2026-08-16 19:13 ` [PATCH v3 49/49] gitlab: --disable-hmp in build-without-defaults Marc-André Lureau
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster,
	Dr. David Alan Gilbert, Peter Xu, Fabiano Rosas, Paolo Bonzini

Move HMP-specific declarations to its own CONFIG_HMP guarded header.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/monitor/hmp.h          |   8 +++-
 migration/migration-hmp-cmds.c |   1 +
 monitor/hmp-cmds.c             |   1 +
 monitor/hmp.c                  |   1 +
 monitor/monitor-hmp-internal.h | 106 +++++++++++++++++++++++++++++++++++++++++
 monitor/monitor-internal.h     |  99 --------------------------------------
 monitor/monitor.c              |   1 +
 monitor/qmp-cmds.c             |   1 +
 stubs/monitor-core.c           |   2 +
 stubs/monitor-internal.c       |   2 +
 tests/unit/test-util-sockets.c |   2 -
 tools/qemu-vnc/stubs.c         |   6 ---
 12 files changed, 121 insertions(+), 109 deletions(-)

diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index f10bf83df86d..ef53e87f7608 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -21,6 +21,10 @@
 #define TYPE_MONITOR_HMP "monitor-hmp"
 OBJECT_DECLARE_TYPE(MonitorHMP, MonitorHMPClass, MONITOR_HMP);
 
+MonitorHMP *monitor_cur_hmp(void);
+
+#ifdef CONFIG_HMP
+
 #define HMP_STUB(cmd) \
     void hmp_##cmd(MonitorHMP *hmp, const QDict *qdict) \
     { \
@@ -36,8 +40,6 @@ struct MonitorDef {
 void monitor_new_hmp(const char *id, const char *chardev_id,
                      bool use_readline, Error **errp);
 
-MonitorHMP *monitor_cur_hmp(void);
-
 int monitor_hmp_vprintf(MonitorHMP *mon, const char *fmt, va_list ap)
     G_GNUC_PRINTF(2, 0);
 int monitor_hmp_printf(MonitorHMP *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
@@ -218,4 +220,6 @@ void hmp_info_skeys(MonitorHMP *hmp, const QDict *qdict);
 void hmp_info_cmma(MonitorHMP *hmp, const QDict *qdict);
 void hmp_migrationmode(MonitorHMP *hmp, const QDict *qdict);
 
+#endif /* CONFIG_HMP */
+
 #endif
diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c
index 6fe189471899..27b38d0e5f85 100644
--- a/migration/migration-hmp-cmds.c
+++ b/migration/migration-hmp-cmds.c
@@ -21,6 +21,7 @@
 #include "monitor/hmp-completion.h"
 #include "monitor/monitor.h"
 #include "monitor/monitor-internal.h"
+#include "monitor/monitor-hmp-internal.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-migration.h"
 #include "qapi/qapi-visit-migration.h"
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 3ac70c3f1123..91701ddf331b 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -25,6 +25,7 @@
 #include "monitor/hmp.h"
 #include "monitor/hmp-completion.h"
 #include "monitor/monitor-internal.h"
+#include "monitor/monitor-hmp-internal.h"
 #include "monitor/qdev.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-control.h"
diff --git a/monitor/hmp.c b/monitor/hmp.c
index e3fc05f521a8..488ec23937df 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -27,6 +27,7 @@
 #include "hw/core/qdev.h"
 #include "hw/core/sysemu-cpu-ops.h"
 #include "monitor-internal.h"
+#include "monitor-hmp-internal.h"
 #include "monitor/hmp.h"
 #include "qobject/qdict.h"
 #include "qobject/qnum.h"
diff --git a/monitor/monitor-hmp-internal.h b/monitor/monitor-hmp-internal.h
new file mode 100644
index 000000000000..4e2430551abf
--- /dev/null
+++ b/monitor/monitor-hmp-internal.h
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef MONITOR_HMP_INTERNAL_H
+#define MONITOR_HMP_INTERNAL_H
+
+#ifdef CONFIG_HMP
+#include "monitor/hmp.h"
+/*
+ * Supported types:
+ *
+ * 'F'          filename
+ * 'B'          block device name
+ * 's'          string (accept optional quote)
+ * 'S'          it just appends the rest of the string (accept optional quote)
+ * 'O'          option string of the form NAME=VALUE,...
+ *              parsed according to QemuOptsList given by its name
+ *              Example: 'device:O' uses qemu_device_opts.
+ *              Restriction: only lists with empty desc are supported
+ *              TODO lift the restriction
+ * 'i'          32 bit integer
+ * 'l'          target long (32 or 64 bit)
+ * 'M'          Non-negative target long (32 or 64 bit), in user mode the
+ *              value is multiplied by 2^20 (think Mebibyte)
+ * 'o'          octets (aka bytes)
+ *              user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
+ *              K, k suffix, which multiplies the value by 2^60 for suffixes E
+ *              and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
+ *              2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
+ * 'T'          double
+ *              user mode accepts an optional ms, us, ns suffix,
+ *              which divides the value by 1e3, 1e6, 1e9, respectively
+ * '/'          optional gdb-like print format (like "/10x")
+ *
+ * '?'          optional type (for all types, except '/')
+ * '.'          other form of optional type (for 'i' and 'l')
+ * 'b'          boolean
+ *              user mode accepts "on" or "off"
+ * '-'          optional parameter (eg. '-f'); if followed by a 's', it
+ *              specifies an optional string param (e.g. '-fs' allows '-f foo')
+ *
+ */
+
+typedef struct HMPCommand {
+    const char *name;
+    const char *args_type;
+    const char *params;
+    const char *help;
+    const char *flags; /* p=preconfig */
+    void (*cmd)(MonitorHMP *hmp, const QDict *qdict);
+    /*
+     * If implementing a command that takes no arguments and simply
+     * prints formatted data, then leave @cmd NULL, and then set
+     * @cmd_info_hrt to the corresponding QMP handler that returns
+     * the formatted text.
+     */
+    HumanReadableText *(*cmd_info_hrt)(Error **errp);
+    /*
+     * @sub_table is a list of 2nd level of commands. If it does not exist,
+     * cmd should be used. If it exists, sub_table[?].cmd should be
+     * used, and cmd of 1st level plays the role of help function.
+     */
+    struct HMPCommand *sub_table;
+    void (*command_completion)(ReadLineState *rs, int nb_args, const char *str);
+
+    /* Keep non-pointer data at the end to minimize holes. */
+
+    /**
+     * @arch_bitmask: bitmask of QEMU_ARCH_* constants
+     *     Allow to restrict the command for a particular set of
+     *     target architectures.
+     */
+    uint32_t arch_bitmask;
+    bool coroutine;
+} HMPCommand;
+
+struct MonitorHMPClass {
+    MonitorClass parent_class;
+};
+
+struct MonitorHMP {
+    Monitor parent_obj;
+    bool use_readline;
+    /*
+     * State used only in the thread "owning" the monitor.
+     * This is currently always the main thread, since
+     * HMP does not allow use of the I/O thread at this time.
+     * These members can be safely accessed without locks.
+     */
+    ReadLineState *rs;
+    char *mon_cpu_path;
+    int reset_seen;
+};
+
+int monitor_hmp_set_cpu(MonitorHMP *hmp, int cpu_index);
+void handle_hmp_command(MonitorHMP *hmp, const char *cmdline);
+int hmp_compare_cmd(const char *name, const char *list);
+
+/*
+ * hmp_cmds_for_target: Return array of HMPCommand entries
+ *
+ * If @info_command is true, return the particular 'info foo' commands array.
+ */
+HMPCommand *hmp_cmds_for_target(bool info_command);
+
+#endif /* CONFIG_HMP */
+#endif
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index c198c12eaa00..822a66d06d00 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -27,7 +27,6 @@
 
 #include "chardev/char-fe.h"
 #include "monitor/monitor.h"
-#include "monitor/hmp.h"
 #include "qapi/qapi-emit-events.h"
 #include "qapi/qapi-types-control.h"
 #include "qapi/qapi-types-qom.h"
@@ -36,75 +35,6 @@
 #include "qemu/readline.h"
 #include "system/iothread.h"
 
-/*
- * Supported types:
- *
- * 'F'          filename
- * 'B'          block device name
- * 's'          string (accept optional quote)
- * 'S'          it just appends the rest of the string (accept optional quote)
- * 'O'          option string of the form NAME=VALUE,...
- *              parsed according to QemuOptsList given by its name
- *              Example: 'device:O' uses qemu_device_opts.
- *              Restriction: only lists with empty desc are supported
- *              TODO lift the restriction
- * 'i'          32 bit integer
- * 'l'          target long (32 or 64 bit)
- * 'M'          Non-negative target long (32 or 64 bit), in user mode the
- *              value is multiplied by 2^20 (think Mebibyte)
- * 'o'          octets (aka bytes)
- *              user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
- *              K, k suffix, which multiplies the value by 2^60 for suffixes E
- *              and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
- *              2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
- * 'T'          double
- *              user mode accepts an optional ms, us, ns suffix,
- *              which divides the value by 1e3, 1e6, 1e9, respectively
- * '/'          optional gdb-like print format (like "/10x")
- *
- * '?'          optional type (for all types, except '/')
- * '.'          other form of optional type (for 'i' and 'l')
- * 'b'          boolean
- *              user mode accepts "on" or "off"
- * '-'          optional parameter (eg. '-f'); if followed by a 's', it
- *              specifies an optional string param (e.g. '-fs' allows '-f foo')
- *
- */
-
-typedef struct HMPCommand {
-    const char *name;
-    const char *args_type;
-    const char *params;
-    const char *help;
-    const char *flags; /* p=preconfig */
-    void (*cmd)(MonitorHMP *mon, const QDict *qdict);
-    /*
-     * If implementing a command that takes no arguments and simply
-     * prints formatted data, then leave @cmd NULL, and then set
-     * @cmd_info_hrt to the corresponding QMP handler that returns
-     * the formatted text.
-     */
-    HumanReadableText *(*cmd_info_hrt)(Error **errp);
-    /*
-     * @sub_table is a list of 2nd level of commands. If it does not exist,
-     * cmd should be used. If it exists, sub_table[?].cmd should be
-     * used, and cmd of 1st level plays the role of help function.
-     */
-    struct HMPCommand *sub_table;
-    void (*command_completion)(ReadLineState *rs, int nb_args, const char *str);
-
-    /* Keep non-pointer data at the end to minimize holes. */
-
-    /**
-     * @arch_bitmask: bitmask of QEMU_ARCH_* constants
-     *     Allow to restrict the command for a particular set of
-     *     target architectures.
-     */
-    uint32_t arch_bitmask;
-    bool coroutine;
-} HMPCommand;
-
-
 struct MonitorClass {
     ObjectClass parent_class;
 
@@ -149,24 +79,6 @@ struct Monitor {
     int mux_out;
 };
 
-struct MonitorHMPClass {
-    MonitorClass parent_class;
-};
-
-struct MonitorHMP {
-    Monitor parent_obj;
-    bool use_readline;
-    /*
-     * State used only in the thread "owning" the monitor.
-     * This is currently always the main thread, since
-     * HMP does not allow use of the I/O thread at this time.
-     * These members can be safely accessed without locks.
-     */
-    ReadLineState *rs;
-    char *mon_cpu_path;
-    int reset_seen;
-};
-
 struct MonitorQMPClass {
     MonitorClass parent_class;
 };
@@ -209,21 +121,10 @@ int monitor_can_read(void *opaque);
 void monitor_cancel_out_watch(Monitor *mon);
 void monitor_list_append(Monitor *mon);
 void monitor_fdsets_cleanup(void);
-int monitor_hmp_set_cpu(MonitorHMP *mon, int cpu_index);
 
 void qmp_send_response(MonitorQMP *mon, const QDict *rsp);
 void monitor_data_destroy_qmp(MonitorQMP *mon);
 void coroutine_fn monitor_qmp_dispatcher_co(void *data);
 void qmp_dispatcher_co_wake(void);
 
-void handle_hmp_command(MonitorHMP *hmp, const char *cmdline);
-int hmp_compare_cmd(const char *name, const char *list);
-
-/*
- * hmp_cmds_for_target: Return array of HMPCommand entries
- *
- * If @info_command is true, return the particular 'info foo' commands array.
- */
-HMPCommand *hmp_cmds_for_target(bool info_command);
-
 #endif
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 7979cd1cbcfd..6ba06280e023 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -24,6 +24,7 @@
 
 #include "qemu/osdep.h"
 #include "monitor-internal.h"
+#include "monitor-hmp-internal.h"
 #include "qapi/error.h"
 #include "qapi/opts-visitor.h"
 #include "qapi/qapi-emit-events.h"
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index c9f24febdc96..7525a88e0494 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -16,6 +16,7 @@
 #include "qemu/osdep.h"
 #include "qemu/sockets.h"
 #include "monitor-internal.h"
+#include "monitor-hmp-internal.h"
 #include "monitor/qdev.h"
 #include "monitor/qmp-helpers.h"
 #include "system/system.h"
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
index 0e74d78d52e4..8dfd46d2a8a3 100644
--- a/stubs/monitor-core.c
+++ b/stubs/monitor-core.c
@@ -1,6 +1,7 @@
 #include "qemu/osdep.h"
 #include "monitor/hmp.h"
 
+#ifdef CONFIG_HMP
 int monitor_hmp_vprintf(MonitorHMP *mon, const char *fmt, va_list ap)
 {
     /*
@@ -17,3 +18,4 @@ int monitor_hmp_vprintf(MonitorHMP *mon, const char *fmt, va_list ap)
     }
     return -1;
 }
+#endif
diff --git a/stubs/monitor-internal.c b/stubs/monitor-internal.c
index 6f69f1f14ae4..4483ca25557f 100644
--- a/stubs/monitor-internal.c
+++ b/stubs/monitor-internal.c
@@ -8,8 +8,10 @@ int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
     return -1;
 }
 
+#ifdef CONFIG_HMP
 void monitor_new_hmp(const char *id, const char *chardev_id,
                      bool use_readline, Error **errp)
 {
     g_assert_not_reached();
 }
+#endif
diff --git a/tests/unit/test-util-sockets.c b/tests/unit/test-util-sockets.c
index 530a3fee3c13..006f5e579c6b 100644
--- a/tests/unit/test-util-sockets.c
+++ b/tests/unit/test-util-sockets.c
@@ -24,7 +24,6 @@
 #include "qapi/error.h"
 #include "socket-helpers.h"
 #include "monitor/monitor.h"
-#include "monitor/hmp.h"
 
 static void test_fd_is_socket_bad(void)
 {
@@ -75,7 +74,6 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
  */
 Monitor *monitor_cur(void) { return cur_mon; }
 Monitor *monitor_set_cur(Coroutine *co, Monitor *mon) { abort(); }
-int monitor_hmp_vprintf(MonitorHMP *mon, const char *fmt, va_list ap) { abort(); }
 
 #ifndef _WIN32
 static void test_socket_fd_pass_name_good(void)
diff --git a/tools/qemu-vnc/stubs.c b/tools/qemu-vnc/stubs.c
index 0aa50a901d37..1e4c14913b56 100644
--- a/tools/qemu-vnc/stubs.c
+++ b/tools/qemu-vnc/stubs.c
@@ -9,7 +9,6 @@
 #include "system/runstate.h"
 #include "hw/core/qdev.h"
 #include "monitor/monitor.h"
-#include "monitor/hmp.h"
 #include "migration/vmstate.h"
 
 bool runstate_is_running(void)
@@ -42,11 +41,6 @@ Monitor *monitor_set_cur(Coroutine *co, Monitor *mon)
     return NULL;
 }
 
-int monitor_hmp_vprintf(MonitorHMP *mon, const char *fmt, va_list ap)
-{
-    return -1;
-}
-
 /*
  * Link-time stubs for VMState symbols referenced by VNC code.
  * The standalone binary never performs migration, so these are

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH v3 49/49] gitlab: --disable-hmp in build-without-defaults
  2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
                   ` (47 preceding siblings ...)
  2026-08-16 19:13 ` [PATCH v3 48/49] monitor: move HMP-specific to monitor-hmp-internal.h Marc-André Lureau
@ 2026-08-16 19:13 ` Marc-André Lureau
  48 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-16 19:13 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
	Daniel P. Berrangé, Markus Armbruster, Alex Bennée,
	Pierrick Bouvier

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 .gitlab-ci.d/buildtest.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
index 831d9a267425..5f21703645b3 100644
--- a/.gitlab-ci.d/buildtest.yml
+++ b/.gitlab-ci.d/buildtest.yml
@@ -673,6 +673,7 @@ build-without-defaults:
       --disable-pie
       --disable-qom-cast-debug
       --disable-strip
+      --disable-hmp
       --target-list-exclude=aarch64-softmmu,mips64-softmmu,mipsel-softmmu,ppc64-softmmu,sh4el-softmmu,xtensa-softmmu,x86_64-softmmu
     MAKE_CHECK_ARGS: check
 

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* Re: [PATCH v3 15/49] tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block
  2026-08-16 19:12 ` [PATCH v3 15/49] tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block Marc-André Lureau
@ 2026-08-16 19:53   ` Denis V. Lunev
  0 siblings, 0 replies; 73+ messages in thread
From: Denis V. Lunev @ 2026-08-16 19:53 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, John Snow, Denis V. Lunev, Fabiano Rosas,
	Laurent Vivier, Paolo Bonzini, qemu-block

On 8/16/26 21:12, Marc-André Lureau wrote:
> The test_cdrom_param() function uses qtest_hmp() to run "info block",
> which depends on the human-monitor-command QMP endpoint. Replace it
> with the QMP query-block command so the test works when HMP is
> disabled (-Dhmp=disabled).
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  tests/qtest/cdrom-test.c | 29 ++++++++++++++++++++++++-----
>  1 file changed, 24 insertions(+), 5 deletions(-)
>
> diff --git a/tests/qtest/cdrom-test.c b/tests/qtest/cdrom-test.c
> index a65854d2bc53..bf997be6d690 100644
> --- a/tests/qtest/cdrom-test.c
> +++ b/tests/qtest/cdrom-test.c
> @@ -14,6 +14,7 @@
>  #include "libqtest.h"
>  #include "boot-sector.h"
>  #include "qobject/qdict.h"
> +#include "qobject/qlist.h"
>  
>  static char isoimage[] = "cdrom-boot-iso-XXXXXX";
>  
> @@ -92,17 +93,35 @@ cleanup:
>  
>  /**
>   * Check that at least the -cdrom parameter is basically working, i.e. we can
> - * see the filename of the ISO image in the output of "info block" afterwards
> + * see the filename of the ISO image in the output of "query-block" afterwards
>   */
>  static void test_cdrom_param(gconstpointer data)
>  {
>      QTestState *qts;
> -    char *resp;
> +    QDict *response;
> +    QList *ret;
> +    QListEntry *entry;
> +    bool found = false;
>  
>      qts = qtest_initf("-M %s -cdrom %s", (const char *)data, isoimage);
> -    resp = qtest_hmp(qts, "info block");
> -    g_assert(strstr(resp, isoimage) != 0);
> -    g_free(resp);
> +    response = qtest_qmp(qts, "{'execute': 'query-block'}");
> +    g_assert(response && qdict_haskey(response, "return"));
> +    ret = qdict_get_qlist(response, "return");
> +
> +    QLIST_FOREACH_ENTRY(ret, entry) {
> +        QDict *entry_dict = qobject_to(QDict, entry->value);
> +        QDict *inserted = qdict_get_qdict(entry_dict, "inserted");
> +        if (inserted) {
> +            const char *file = qdict_get_str(inserted, "file");
> +            if (file && strstr(file, isoimage)) {
> +                found = true;
> +                break;
> +            }
> +        }
> +    }
> +
> +    g_assert(found);
> +    qobject_unref(response);
>      qtest_quit(qts);
>  }
>  
>
Reviewed-by: Denis V. Lunev <den@openvz.org>


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

* Re: [PATCH v3 23/49] qtest/ide-test: convert to use qtest qemu-io command
  2026-08-16 19:12 ` [PATCH v3 23/49] qtest/ide-test: convert to use qtest qemu-io command Marc-André Lureau
@ 2026-08-16 19:54   ` Denis V. Lunev
  0 siblings, 0 replies; 73+ messages in thread
From: Denis V. Lunev @ 2026-08-16 19:54 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, John Snow, Denis V. Lunev, Fabiano Rosas,
	Laurent Vivier, Paolo Bonzini, qemu-block

On 8/16/26 21:12, Marc-André Lureau wrote:
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  tests/qtest/ahci-test.c | 5 ++---
>  tests/qtest/ide-test.c  | 4 ++--
>  2 files changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/tests/qtest/ahci-test.c b/tests/qtest/ahci-test.c
> index 71d23fe56af7..0528a422fafc 100644
> --- a/tests/qtest/ahci-test.c
> +++ b/tests/qtest/ahci-test.c
> @@ -1719,8 +1719,7 @@ static void test_atapi_engine_restart_in_flight(bool dma)
>      qtest_memset(ahci->parent->qts, buffer, 0x00, ATAPI_SECTOR_SIZE);
>  
>      /* Suspend the next backend read so the ATAPI read stays in flight. */
> -    g_free(qtest_hmp(ahci->parent->qts,
> -                     "qemu-io drive0 \"break read_aio rd\""));
> +    qtest_qemu_io(ahci->parent->qts, "drive0", "break read_aio rd");
>  
>      cmd = ahci_atapi_command_create(CMD_ATAPI_READ_10, ATAPI_SECTOR_SIZE,
>                                      dma);
> @@ -1732,7 +1731,7 @@ static void test_atapi_engine_restart_in_flight(bool dma)
>      ahci_px_clr(ahci, port, AHCI_PX_CMD, AHCI_PX_CMD_ST);
>      ahci_px_set(ahci, port, AHCI_PX_CMD, AHCI_PX_CMD_ST);
>  
> -    g_free(qtest_hmp(ahci->parent->qts, "qemu-io drive0 \"resume rd\""));
> +    qtest_qemu_io(ahci->parent->qts, "drive0", "resume rd");
>  
>      /* Round-trip through the device to confirm qemu is still alive. */
>      ahci_px_rreg(ahci, port, AHCI_PX_TFD);
> diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c
> index b36b0f8875b2..31692f6925ac 100644
> --- a/tests/qtest/ide-test.c
> +++ b/tests/qtest/ide-test.c
> @@ -836,7 +836,7 @@ static void test_flush(void)
>      make_dirty(qts, 0);
>  
>      /* Delay the completion of the flush request until we explicitly do it */
> -    g_free(qtest_hmp(qts, "qemu-io ide0-hd0 \"break flush_to_os A\""));
> +    qtest_qemu_io(qts, "ide0-hd0", "break flush_to_os A");
>  
>      /* FLUSH CACHE command on device 0*/
>      qpci_io_writeb(dev, ide_bar, reg_device, 0);
> @@ -848,7 +848,7 @@ static void test_flush(void)
>      assert_bit_clear(data, DF | ERR | DRQ);
>  
>      /* Complete the command */
> -    g_free(qtest_hmp(qts, "qemu-io ide0-hd0 \"resume A\""));
> +    qtest_qemu_io(qts, "ide0-hd0", "resume A");
>  
>      /* Check registers */
>      data = qpci_io_readb(dev, ide_bar, reg_device);
>
Reviewed-by: Denis V. Lunev <den@openvz.org>


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

* Re: [PATCH v3 30/49] monitor: isolate HMP declarations in hmp.h
  2026-08-16 19:12 ` [PATCH v3 30/49] monitor: isolate HMP declarations in hmp.h Marc-André Lureau
@ 2026-08-16 20:21   ` Dr. David Alan Gilbert
  0 siblings, 0 replies; 73+ messages in thread
From: Dr. David Alan Gilbert @ 2026-08-16 20:21 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Richard Henderson, Paolo Bonzini,
	Alex Bennée, Laurent Vivier, Amit Shah, Michael S. Tsirkin,
	Brian Cain, Pierrick Bouvier, Stefano Stabellini, Anthony PERARD,
	Edgar E. Iglesias, Samuel Thibault, Jason Wang, Yoshinori Sato,
	Stefan Hajnoczi, xen-devel

* Marc-André Lureau (marcandre.lureau@redhat.com) wrote:
> Also rename password & commands with hmp in the name, while at it.
> Other functions need larger changes which we will take care of next.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Dr. David Alan Gilbert <dave@treblig.org>

> ---
>  accel/accel-system.c           |  1 +
>  accel/tcg/monitor.c            |  1 +
>  chardev/char.c                 |  2 +-
>  disas/disas-mon.c              |  1 +
>  gdbstub/system.c               |  2 +-
>  hw/char/virtio-serial-bus.c    |  1 +
>  hw/core/machine-hmp-cmds.c     |  1 -
>  hw/core/sysbus.c               |  1 +
>  hw/hexagon/hexagon_tlb.c       |  1 +
>  hw/misc/auxbus.c               |  1 +
>  hw/usb/bus.c                   |  1 +
>  hw/usb/host-libusb.c           |  1 +
>  hw/xen/xen-bus.c               |  1 +
>  include/monitor/hmp.h          | 21 +++++++++++++++++++++
>  include/monitor/monitor.h      | 18 ------------------
>  monitor/hmp.c                  |  8 ++++----
>  monitor/monitor-internal.h     |  1 +
>  net/slirp.c                    |  1 +
>  stubs/monitor-core.c           |  1 +
>  stubs/monitor-internal.c       |  2 +-
>  target/rx/disas.c              |  1 +
>  tests/unit/test-util-sockets.c |  1 +
>  tools/qemu-vnc/stubs.c         |  1 +
>  trace/trace-hmp-cmds.c         |  1 -
>  ui/ui-hmp-cmds.c               |  4 ++--
>  util/error-report.c            |  2 +-
>  util/qemu-print.c              |  1 +
>  27 files changed, 48 insertions(+), 30 deletions(-)
> 
> diff --git a/accel/accel-system.c b/accel/accel-system.c
> index 9176665202d2..977804c4048a 100644
> --- a/accel/accel-system.c
> +++ b/accel/accel-system.c
> @@ -28,6 +28,7 @@
>  #include "qom/compat-properties.h"
>  #include "qapi/qapi-commands-accelerator.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "hw/core/boards.h"
>  #include "hw/core/cpu.h"
>  #include "accel/accel-ops.h"
> diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c
> index be5c1950177c..74170ddef708 100644
> --- a/accel/tcg/monitor.c
> +++ b/accel/tcg/monitor.c
> @@ -11,6 +11,7 @@
>  #include "qapi/type-helpers.h"
>  #include "qapi/qapi-commands-machine.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "system/tcg.h"
>  #include "tcg/tcg.h"
>  #include "internal-common.h"
> diff --git a/chardev/char.c b/chardev/char.c
> index c6c8133f5c1d..9da0911e503c 100644
> --- a/chardev/char.c
> +++ b/chardev/char.c
> @@ -24,7 +24,7 @@
>  
>  #include "qemu/osdep.h"
>  #include "qemu/cutils.h"
> -#include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "monitor/qmp-helpers.h"
>  #include "qemu/config-file.h"
>  #include "qemu/error-report.h"
> diff --git a/disas/disas-mon.c b/disas/disas-mon.c
> index 9c693618c277..bc9dec3a7761 100644
> --- a/disas/disas-mon.c
> +++ b/disas/disas-mon.c
> @@ -10,6 +10,7 @@
>  #include "system/memory.h"
>  #include "hw/core/cpu.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  
>  /*
>   * Get LENGTH bytes from info's buffer, at target address memaddr.
> diff --git a/gdbstub/system.c b/gdbstub/system.c
> index 070bc26f416c..8a1cdb11db36 100644
> --- a/gdbstub/system.c
> +++ b/gdbstub/system.c
> @@ -29,7 +29,7 @@
>  #include "hw/core/boards.h"
>  #include "chardev/char.h"
>  #include "chardev/char-fe.h"
> -#include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "trace.h"
>  #include "internals.h"
>  
> diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
> index c1973f0248fc..02604740f86a 100644
> --- a/hw/char/virtio-serial-bus.c
> +++ b/hw/char/virtio-serial-bus.c
> @@ -25,6 +25,7 @@
>  #include "qemu/module.h"
>  #include "migration/qemu-file-types.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "qemu/error-report.h"
>  #include "qemu/queue.h"
>  #include "hw/core/qdev-properties.h"
> diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
> index 686304bafab5..1c700aad3587 100644
> --- a/hw/core/machine-hmp-cmds.c
> +++ b/hw/core/machine-hmp-cmds.c
> @@ -15,7 +15,6 @@
>  
>  #include "qemu/osdep.h"
>  #include "monitor/hmp.h"
> -#include "monitor/monitor.h"
>  #include "qapi/error.h"
>  #include "qapi/qapi-builtin-visit.h"
>  #include "qapi/qapi-commands-accelerator.h"
> diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
> index 3e1160ee921d..13df7cbafe10 100644
> --- a/hw/core/sysbus.c
> +++ b/hw/core/sysbus.c
> @@ -21,6 +21,7 @@
>  #include "qapi/error.h"
>  #include "hw/core/sysbus.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "system/address-spaces.h"
>  
>  static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
> diff --git a/hw/hexagon/hexagon_tlb.c b/hw/hexagon/hexagon_tlb.c
> index b6d4aff389e5..2d878cee736d 100644
> --- a/hw/hexagon/hexagon_tlb.c
> +++ b/hw/hexagon/hexagon_tlb.c
> @@ -12,6 +12,7 @@
>  #include "hw/core/resettable.h"
>  #include "migration/vmstate.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "qapi/error.h"
>  #include "exec/page-protection.h"
>  #include "exec/target_page.h"
> diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
> index 877f34560626..ac2525b90fec 100644
> --- a/hw/misc/auxbus.c
> +++ b/hw/misc/auxbus.c
> @@ -33,6 +33,7 @@
>  #include "hw/misc/auxbus.h"
>  #include "hw/i2c/i2c.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "qapi/error.h"
>  
>  #ifndef DEBUG_AUX
> diff --git a/hw/usb/bus.c b/hw/usb/bus.c
> index 3b6fbd46ac3f..9b9b2e7c2f8f 100644
> --- a/hw/usb/bus.c
> +++ b/hw/usb/bus.c
> @@ -9,6 +9,7 @@
>  #include "system/system.h"
>  #include "migration/vmstate.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "trace.h"
>  #include "qemu/cutils.h"
>  
> diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
> index b9f3ad3f66dd..af67d5dfeb10 100644
> --- a/hw/usb/host-libusb.c
> +++ b/hw/usb/host-libusb.c
> @@ -48,6 +48,7 @@
>  #include "qapi/error.h"
>  #include "migration/vmstate.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "qemu/error-report.h"
>  #include "qemu/main-loop.h"
>  #include "qemu/module.h"
> diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
> index dfad2bc5085f..a563f6066bb4 100644
> --- a/hw/xen/xen-bus.c
> +++ b/hw/xen/xen-bus.c
> @@ -17,6 +17,7 @@
>  #include "hw/xen/xen-bus.h"
>  #include "hw/xen/xen-bus-helper.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "qapi/error.h"
>  #include "qobject/qdict.h"
>  #include "system/system.h"
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index 9258a049bffb..166cd4100c63 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -18,6 +18,9 @@
>  #include "qapi/qapi-types-common.h"
>  #include "monitor/monitor.h"
>  
> +#define TYPE_MONITOR_HMP "monitor-hmp"
> +OBJECT_DECLARE_TYPE(MonitorHMP, MonitorHMPClass, MONITOR_HMP);
> +
>  #define HMP_STUB(cmd) \
>      void hmp_##cmd(Monitor *mon, const QDict *qdict) \
>      { \
> @@ -30,6 +33,24 @@ struct MonitorDef {
>      int64_t (*get_value)(Monitor *mon, const MonitorDef *md, int offset);
>  };
>  
> +void monitor_new_hmp(const char *id, const char *chardev_id,
> +                     bool use_readline, Error **errp);
> +
> +int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
> +    G_GNUC_PRINTF(2, 0);
> +int monitor_printf(Monitor *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
> +void monitor_printc(Monitor *mon, int ch);
> +
> +void monitor_hmp_read_command(MonitorHMP *hmp, int show_prompt);
> +int monitor_hmp_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
> +                              void *opaque);
> +
> +void monitor_register_hmp(const char *name, bool info,
> +                          void (*cmd)(Monitor *mon, const QDict *qdict));
> +void monitor_register_hmp_info_hrt(const char *name,
> +                                   HumanReadableText *(*handler)(Error **errp));
> +
> +
>  CPUArchState *mon_get_cpu_env(Monitor *mon);
>  CPUState *mon_get_cpu(Monitor *mon);
>  
> diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
> index 9f048ba103b5..72a8f6ea5b4f 100644
> --- a/include/monitor/monitor.h
> +++ b/include/monitor/monitor.h
> @@ -10,9 +10,6 @@
>  #define TYPE_MONITOR "monitor"
>  OBJECT_DECLARE_TYPE(Monitor, MonitorClass, MONITOR);
>  
> -#define TYPE_MONITOR_HMP "monitor-hmp"
> -OBJECT_DECLARE_TYPE(MonitorHMP, MonitorHMPClass, MONITOR_HMP);
> -
>  #define TYPE_MONITOR_QMP "monitor-qmp"
>  OBJECT_DECLARE_TYPE(MonitorQMP, MonitorQMPClass, MONITOR_QMP);
>  
> @@ -30,8 +27,6 @@ void monitor_init_globals_core(void);
>  char *monitor_compat_id(void);
>  void monitor_new_qmp(const char *id, const char *chardev_id,
>                       bool pretty, Error **errp);
> -void monitor_new_hmp(const char *id, const char *chardev_id,
> -                     bool use_readline, Error **errp);
>  int monitor_new(MonitorOptions *opts, bool allow_hmp, Error **errp);
>  int monitor_new_opts(QemuOpts *opts, Error **errp);
>  void monitor_cleanup(void);
> @@ -43,28 +38,15 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp);
>  int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp);
>  
>  int monitor_puts(Monitor *mon, const char *str);
> -int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
> -    G_GNUC_PRINTF(2, 0);
> -int monitor_printf(Monitor *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
> -void monitor_printc(Monitor *mon, int ch);
>  void monitor_flush(Monitor *mon);
>  int monitor_get_cpu_index(Monitor *mon);
>  
>  int monitor_puts_locked(Monitor *mon, const char *str);
>  void monitor_flush_locked(Monitor *mon);
>  
> -void monitor_read_command(MonitorHMP *hmp, int show_prompt);
> -int monitor_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
> -                          void *opaque);
> -
>  AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id,
>                                  const char *opaque, Error **errp);
>  int monitor_fdset_dup_fd_add(int64_t fdset_id, int flags, Error **errp);
>  void monitor_fdset_dup_fd_remove(int dup_fd);
>  
> -void monitor_register_hmp(const char *name, bool info,
> -                          void (*cmd)(Monitor *mon, const QDict *qdict));
> -void monitor_register_hmp_info_hrt(const char *name,
> -                                   HumanReadableText *(*handler)(Error **errp));
> -
>  #endif /* MONITOR_H */
> diff --git a/monitor/hmp.c b/monitor/hmp.c
> index 8134dfaad4bb..b4d05d47c4bf 100644
> --- a/monitor/hmp.c
> +++ b/monitor/hmp.c
> @@ -136,7 +136,7 @@ static void monitor_command_cb(void *opaque, const char *cmdline,
>      monitor_resume(&hmp->parent_obj);
>  }
>  
> -void monitor_read_command(MonitorHMP *hmp, int show_prompt)
> +void monitor_hmp_read_command(MonitorHMP *hmp, int show_prompt)
>  {
>      if (!hmp->rs) {
>          return;
> @@ -148,8 +148,8 @@ void monitor_read_command(MonitorHMP *hmp, int show_prompt)
>      }
>  }
>  
> -int monitor_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
> -                          void *opaque)
> +int monitor_hmp_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
> +                              void *opaque)
>  {
>      if (hmp->rs) {
>          readline_start(hmp->rs, "Password: ", 1, readline_func, opaque);
> @@ -1647,7 +1647,7 @@ static void monitor_hmp_complete(UserCreatable *uc, Error **errp)
>                                      monitor_readline_flush,
>                                      hmp,
>                                      monitor_find_completion);
> -            monitor_read_command(hmp, 0);
> +            monitor_hmp_read_command(hmp, 0);
>          }
>  
>          qemu_chr_fe_set_handlers(&hmp->parent_obj.chr,
> diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
> index fdeeeb853636..ee9ba0c8231e 100644
> --- a/monitor/monitor-internal.h
> +++ b/monitor/monitor-internal.h
> @@ -27,6 +27,7 @@
>  
>  #include "chardev/char-fe.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "qapi/qapi-emit-events.h"
>  #include "qapi/qapi-types-control.h"
>  #include "qapi/qapi-types-qom.h"
> diff --git a/net/slirp.c b/net/slirp.c
> index 517dd23be14b..9bf09a2c8bc9 100644
> --- a/net/slirp.c
> +++ b/net/slirp.c
> @@ -36,6 +36,7 @@
>  #include "clients.h"
>  #include "hub.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "qemu/error-report.h"
>  #include "qemu/sockets.h"
>  #include <libslirp.h>
> diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
> index a7c32297c90a..b0c7002bd406 100644
> --- a/stubs/monitor-core.c
> +++ b/stubs/monitor-core.c
> @@ -1,5 +1,6 @@
>  #include "qemu/osdep.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "qapi/qapi-emit-events.h"
>  
>  Monitor *monitor_cur(void)
> diff --git a/stubs/monitor-internal.c b/stubs/monitor-internal.c
> index 731fad221ecc..6f69f1f14ae4 100644
> --- a/stubs/monitor-internal.c
> +++ b/stubs/monitor-internal.c
> @@ -1,6 +1,6 @@
>  #include "qemu/osdep.h"
>  #include "qapi/error.h"
> -#include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  
>  int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
>  {
> diff --git a/target/rx/disas.c b/target/rx/disas.c
> index 67b932882914..0eb2ee6f4507 100644
> --- a/target/rx/disas.c
> +++ b/target/rx/disas.c
> @@ -19,6 +19,7 @@
>  #include "qemu/osdep.h"
>  #include "disas/dis-asm.h"
>  #include "qemu/bitops.h"
> +#include "monitor/hmp.h"
>  #include "cpu.h"
>  
>  typedef struct DisasContext {
> diff --git a/tests/unit/test-util-sockets.c b/tests/unit/test-util-sockets.c
> index ab3f39c3efb5..b2a884529598 100644
> --- a/tests/unit/test-util-sockets.c
> +++ b/tests/unit/test-util-sockets.c
> @@ -24,6 +24,7 @@
>  #include "qapi/error.h"
>  #include "socket-helpers.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  
>  static void test_fd_is_socket_bad(void)
>  {
> diff --git a/tools/qemu-vnc/stubs.c b/tools/qemu-vnc/stubs.c
> index 1c82d8cff430..26597fefaa99 100644
> --- a/tools/qemu-vnc/stubs.c
> +++ b/tools/qemu-vnc/stubs.c
> @@ -9,6 +9,7 @@
>  #include "system/runstate.h"
>  #include "hw/core/qdev.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "migration/vmstate.h"
>  
>  bool runstate_is_running(void)
> diff --git a/trace/trace-hmp-cmds.c b/trace/trace-hmp-cmds.c
> index 390173095cff..c8f0133abecf 100644
> --- a/trace/trace-hmp-cmds.c
> +++ b/trace/trace-hmp-cmds.c
> @@ -25,7 +25,6 @@
>  #include "qemu/osdep.h"
>  #include "monitor/hmp.h"
>  #include "monitor/hmp-completion.h"
> -#include "monitor/monitor.h"
>  #include "qapi/error.h"
>  #include "qapi/qapi-commands-trace.h"
>  #include "qobject/qdict.h"
> diff --git a/ui/ui-hmp-cmds.c b/ui/ui-hmp-cmds.c
> index 806a7bece7cb..4ef459490ba2 100644
> --- a/ui/ui-hmp-cmds.c
> +++ b/ui/ui-hmp-cmds.c
> @@ -327,7 +327,7 @@ static void hmp_change_read_arg(void *opaque, const char *password,
>                                  void *readline_opaque)
>  {
>      qmp_change_vnc_password(password, NULL);
> -    monitor_read_command(opaque, 1);
> +    monitor_hmp_read_command(opaque, 1);
>  }
>  
>  void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
> @@ -344,7 +344,7 @@ void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
>      }
>      if (!arg) {
>          MonitorHMP *hmp = MONITOR_HMP(mon);
> -        monitor_read_password(hmp, hmp_change_read_arg, NULL);
> +        monitor_hmp_read_password(hmp, hmp_change_read_arg, NULL);
>      } else {
>          qmp_change_vnc_password(arg, errp);
>      }
> diff --git a/util/error-report.c b/util/error-report.c
> index f333af9249b9..aaa15bc79827 100644
> --- a/util/error-report.c
> +++ b/util/error-report.c
> @@ -11,7 +11,7 @@
>   */
>  
>  #include "qemu/osdep.h"
> -#include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "qemu/error-report.h"
>  
>  /*
> diff --git a/util/qemu-print.c b/util/qemu-print.c
> index 7b9591035e57..a2d1f0244168 100644
> --- a/util/qemu-print.c
> +++ b/util/qemu-print.c
> @@ -12,6 +12,7 @@
>  
>  #include "qemu/osdep.h"
>  #include "monitor/monitor.h"
> +#include "monitor/hmp.h"
>  #include "qemu/qemu-print.h"
>  
>  /*
> 
> -- 
> 2.55.0.543.g5ebe2ebe4ea8
> 
-- 
 -----Open up your eyes, open up your mind, open up your code -------   
/ Dr. David Alan Gilbert    |       Running GNU/Linux       | Happy  \ 
\        dave @ treblig.org |                               | In Hex /
 \ _________________________|_____ http://www.treblig.org   |_______/


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

* Re: [PATCH v3 27/49] monitor: reject readline monitor when HMP is disabled
  2026-08-16 19:12 ` [PATCH v3 27/49] monitor: reject readline monitor when HMP is disabled Marc-André Lureau
@ 2026-08-16 20:23   ` Dr. David Alan Gilbert
  0 siblings, 0 replies; 73+ messages in thread
From: Dr. David Alan Gilbert @ 2026-08-16 20:23 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster

* Marc-André Lureau (marcandre.lureau@redhat.com) wrote:
> When QEMU is built without HMP support, reject '-monitor' (which
> requests readline/HMP mode) early in monitor_new_opts() with a
> clear error message directing users to '-qmp' instead.
> 
> Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Dr. David Alan Gilbert <dave@treblig.org>

> ---
>  monitor/monitor.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/monitor/monitor.c b/monitor/monitor.c
> index 6d6ffbb0f78a..8528af6f79b8 100644
> --- a/monitor/monitor.c
> +++ b/monitor/monitor.c
> @@ -776,6 +776,16 @@ int monitor_new_opts(QemuOpts *opts, Error **errp)
>      MonitorOptions *options;
>      int ret;
>  
> +#ifndef CONFIG_HMP
> +    const char *mode = qemu_opt_get(opts, "mode");
> +    /* readline is HMP..  */
> +    if (mode && g_str_equal(mode, "readline")) {
> +        error_setg(errp, "HMP monitor is not available,"
> +                   " use '-qmp' instead of '-monitor'");
> +        return -1;
> +    }
> +#endif
> +
>      v = opts_visitor_new(opts);
>      visit_type_MonitorOptions(v, NULL, &options, errp);
>      visit_free(v);
> 
> -- 
> 2.55.0.543.g5ebe2ebe4ea8
> 
-- 
 -----Open up your eyes, open up your mind, open up your code -------   
/ Dr. David Alan Gilbert    |       Running GNU/Linux       | Happy  \ 
\        dave @ treblig.org |                               | In Hex /
 \ _________________________|_____ http://www.treblig.org   |_______/


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

* Re: [PATCH v3 31/49] monitor: change HMPCommand cmd to take MonitorHMP
  2026-08-16 19:12 ` [PATCH v3 31/49] monitor: change HMPCommand cmd to take MonitorHMP Marc-André Lureau
@ 2026-08-16 21:51   ` Dr. David Alan Gilbert
  2026-08-17 18:08     ` Jason J. Herne
  0 siblings, 1 reply; 73+ messages in thread
From: Dr. David Alan Gilbert @ 2026-08-16 21:51 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Gerd Hoffmann, Gonglei (Arei), zhenwei pi,
	Kevin Wolf, Hanna Reitz, Paolo Bonzini, Ani Sinha,
	David Woodhouse, Paul Durrant, Michael S. Tsirkin,
	Richard Henderson, Marcelo Tosatti, Mark Cave-Ayland, Jiri Pirko,
	Jason Wang, Halil Pasic, Christian Borntraeger, Jason Herne,
	Ilya Leoshkevich, David Hildenbrand, Eric Farman, Matthew Rosato,
	Cornelia Huck, Samuel Thibault, Hyman Huang, Peter Xu,
	Fabiano Rosas, Alex Bennée, Stefan Berger, Zhao Liu,
	Laurent Vivier, Nicholas Piggin, Chinmay Rath, Glenn Miles,
	Harsh Prateek Bora, Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Yoshinori Sato,
	Artyom Tarasenko, Max Filippov, Stefan Hajnoczi, qemu-block, kvm,
	qemu-ppc, qemu-s390x, qemu-riscv

* Marc-André Lureau (marcandre.lureau@redhat.com) wrote:
> 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.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Dr. David Alan Gilbert <dave@treblig.org>

> ---
>  audio/audio-hmp-cmds.c          |   8 +-
>  backends/cryptodev-hmp-cmds.c   |   3 +-
>  block/monitor/block-hmp-cmds.c  |  78 +++++++----
>  chardev/char-hmp-cmds.c         |  21 ++-
>  dump/dump-hmp-cmds.c            |   6 +-
>  hw/core/machine-hmp-cmds.c      |  49 ++++---
>  hw/i386/kvm/xen-stubs.c         |   6 +-
>  hw/i386/kvm/xen_evtchn.c        |   6 +-
>  hw/i386/sgx-hmp-stub.c          |   3 +-
>  hw/i386/sgx.c                   |   3 +-
>  hw/misc/mos6522-stub.c          |   3 +-
>  hw/misc/mos6522.c               |   3 +-
>  hw/net/rocker/rocker-hmp-cmds.c |  12 +-
>  hw/pci/pci-hmp-cmds.c           |   6 +-
>  hw/pci/pci-stub.c               |   5 +-
>  hw/s390x/s390-skeys.c           |   5 +-
>  hw/s390x/s390-stattrib.c        |   6 +-
>  hw/uefi/ovmf-log.c              |   3 +-
>  hw/usb/host-libusb.c            |   3 +-
>  hw/virtio/virtio-hmp-cmds.c     |  15 +-
>  include/block/block-hmp-cmds.h  |  55 ++++----
>  include/hw/usb/usb.h            |   3 +-
>  include/monitor/hmp.h           | 294 ++++++++++++++++++++--------------------
>  include/monitor/qdev.h          |   5 +-
>  include/net/net.h               |   5 +-
>  include/net/slirp.h             |   8 +-
>  migration/dirtyrate.c           |   6 +-
>  migration/migration-hmp-cmds.c  |  48 ++++---
>  monitor/hmp-cmds.c              |  96 ++++++++-----
>  monitor/hmp.c                   |  17 ++-
>  monitor/monitor-internal.h      |   2 +-
>  net/net-hmp-cmds.c              |  14 +-
>  net/slirp.c                     |   9 +-
>  qom/qom-hmp-cmds.c              |  18 ++-
>  replay/replay-debugging.c       |   9 +-
>  replay/stubs-system.c           |   8 +-
>  stats/stats-hmp-cmds.c          |   3 +-
>  stubs/hmp-cmd-info_sev.c        |   3 +-
>  system/dirtylimit-hmp-cmds.c    |   9 +-
>  system/qdev-monitor.c           |  11 +-
>  system/runstate-hmp-cmds.c      |   9 +-
>  system/tpm-hmp-cmds.c           |   3 +-
>  target/i386/cpu-apic.c          |   3 +-
>  target/i386/monitor.c           |   9 +-
>  target/i386/sev.c               |   3 +-
>  target/m68k/monitor.c           |   3 +-
>  target/ppc/monitor.c            |   3 +-
>  target/riscv/monitor.c          |   3 +-
>  target/sh4/monitor.c            |   3 +-
>  target/sparc/monitor.c          |   3 +-
>  target/xtensa/monitor.c         |   3 +-
>  trace/trace-hmp-cmds.c          |   8 +-
>  ui/ui-hmp-cmds.c                |  31 +++--
>  53 files changed, 561 insertions(+), 390 deletions(-)
> 
> diff --git a/audio/audio-hmp-cmds.c b/audio/audio-hmp-cmds.c
> index 1ffb5ebc7420..4d326ec99fdf 100644
> --- a/audio/audio-hmp-cmds.c
> +++ b/audio/audio-hmp-cmds.c
> @@ -32,8 +32,9 @@
>  
>  static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
>  
> -void hmp_info_capture(Monitor *mon, const QDict *qdict)
> +void hmp_info_capture(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int i;
>      CaptureState *s;
>  
> @@ -45,7 +46,7 @@ void hmp_info_capture(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_stopcapture(Monitor *mon, const QDict *qdict)
> +void hmp_stopcapture(MonitorHMP *hmp, const QDict *qdict)
>  {
>      int i;
>      int n = qdict_get_int(qdict, "n");
> @@ -63,8 +64,9 @@ void hmp_stopcapture(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_wavcapture(Monitor *mon, const QDict *qdict)
> +void hmp_wavcapture(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *path = qdict_get_str(qdict, "path");
>      int freq = qdict_get_try_int(qdict, "freq", 44100);
>      int bits = qdict_get_try_int(qdict, "bits", 16);
> diff --git a/backends/cryptodev-hmp-cmds.c b/backends/cryptodev-hmp-cmds.c
> index 01396d227c88..fb62428d795a 100644
> --- a/backends/cryptodev-hmp-cmds.c
> +++ b/backends/cryptodev-hmp-cmds.c
> @@ -17,8 +17,9 @@
>  #include "qobject/qdict.h"
>  
>  
> -void hmp_info_cryptodev(Monitor *mon, const QDict *qdict)
> +void hmp_info_cryptodev(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      QCryptodevInfoList *il;
>      QCryptodevBackendServiceTypeList *sl;
>      QCryptodevBackendClientList *cl;
> diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
> index 22fa03089ea3..3914b5189d56 100644
> --- a/block/monitor/block-hmp-cmds.c
> +++ b/block/monitor/block-hmp-cmds.c
> @@ -87,8 +87,9 @@ out:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_drive_add(Monitor *mon, const QDict *qdict)
> +void hmp_drive_add(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      DriveInfo *dinfo;
>      QemuOpts *opts;
> @@ -135,8 +136,9 @@ err:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_drive_del(Monitor *mon, const QDict *qdict)
> +void hmp_drive_del(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *id = qdict_get_str(qdict, "id");
>      BlockBackend *blk;
>      BlockDriverState *bs;
> @@ -194,8 +196,9 @@ unlock:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_commit(Monitor *mon, const QDict *qdict)
> +void hmp_commit(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      BlockBackend *blk;
>      int ret;
> @@ -232,8 +235,9 @@ end:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
> +void hmp_drive_mirror(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *filename = qdict_get_str(qdict, "target");
>      const char *format = qdict_get_try_str(qdict, "format");
>      bool reuse = qdict_get_try_bool(qdict, "reuse", false);
> @@ -258,8 +262,9 @@ end:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_drive_backup(Monitor *mon, const QDict *qdict)
> +void hmp_drive_backup(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *filename = qdict_get_str(qdict, "target");
>      const char *format = qdict_get_try_str(qdict, "format");
> @@ -288,8 +293,9 @@ end:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
> +void hmp_block_job_set_speed(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *error = NULL;
>      const char *device = qdict_get_str(qdict, "device");
>      int64_t value = qdict_get_int(qdict, "speed");
> @@ -299,8 +305,9 @@ void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, error);
>  }
>  
> -void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
> +void hmp_block_job_cancel(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *error = NULL;
>      const char *device = qdict_get_str(qdict, "device");
>      bool force = qdict_get_try_bool(qdict, "force", false);
> @@ -310,8 +317,9 @@ void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, error);
>  }
>  
> -void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
> +void hmp_block_job_pause(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *error = NULL;
>      const char *device = qdict_get_str(qdict, "device");
>  
> @@ -320,8 +328,9 @@ void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, error);
>  }
>  
> -void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
> +void hmp_block_job_resume(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *error = NULL;
>      const char *device = qdict_get_str(qdict, "device");
>  
> @@ -330,8 +339,9 @@ void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, error);
>  }
>  
> -void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
> +void hmp_block_job_complete(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *error = NULL;
>      const char *device = qdict_get_str(qdict, "device");
>  
> @@ -340,8 +350,9 @@ void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, error);
>  }
>  
> -void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
> +void hmp_snapshot_blkdev(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *filename = qdict_get_str(qdict, "snapshot-file");
>      const char *format = qdict_get_try_str(qdict, "format");
> @@ -355,8 +366,9 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
> +void hmp_snapshot_blkdev_internal(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *name = qdict_get_str(qdict, "name");
>      Error *err = NULL;
> @@ -365,8 +377,9 @@ void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
> +void hmp_snapshot_delete_blkdev_internal(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *name = qdict_get_str(qdict, "name");
>      const char *id = qdict_get_try_str(qdict, "id");
> @@ -376,8 +389,9 @@ void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
> +void hmp_nbd_server_start(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *uri = qdict_get_str(qdict, "uri");
>      bool writable = qdict_get_try_bool(qdict, "writable", false);
>      bool all = qdict_get_try_bool(qdict, "all", false);
> @@ -438,8 +452,9 @@ exit:
>      hmp_handle_error(mon, local_err);
>  }
>  
> -void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
> +void hmp_nbd_server_add(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *name = qdict_get_try_str(qdict, "name");
>      bool writable = qdict_get_try_bool(qdict, "writable", false);
> @@ -456,8 +471,9 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, local_err);
>  }
>  
> -void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict)
> +void hmp_nbd_server_remove(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *name = qdict_get_str(qdict, "name");
>      bool force = qdict_get_try_bool(qdict, "force", false);
>      Error *err = NULL;
> @@ -467,16 +483,18 @@ void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
> +void hmp_nbd_server_stop(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_nbd_server_stop(&err);
>      hmp_handle_error(mon, err);
>  }
>  
> -void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict)
> +void coroutine_fn hmp_block_resize(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      int64_t size = qdict_get_int(qdict, "size");
>      Error *err = NULL;
> @@ -485,8 +503,9 @@ void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_block_stream(Monitor *mon, const QDict *qdict)
> +void hmp_block_stream(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *error = NULL;
>      const char *device = qdict_get_str(qdict, "device");
>      const char *base = qdict_get_try_str(qdict, "base");
> @@ -500,8 +519,9 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, error);
>  }
>  
> -void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
> +void hmp_block_set_io_throttle(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      char *device = (char *) qdict_get_str(qdict, "device");
>      BlockIOThrottle throttle = {
> @@ -528,8 +548,9 @@ void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_eject(Monitor *mon, const QDict *qdict)
> +void hmp_eject(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      bool force = qdict_get_try_bool(qdict, "force", false);
>      const char *device = qdict_get_str(qdict, "device");
>      Error *err = NULL;
> @@ -538,8 +559,9 @@ void hmp_eject(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_qemu_io(Monitor *mon, const QDict *qdict)
> +void hmp_qemu_io(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      bool qdev = qdict_get_try_bool(qdict, "qdev", false);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *command = qdict_get_str(qdict, "command");
> @@ -666,8 +688,9 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
>      }
>  }
>  
> -void hmp_info_block(Monitor *mon, const QDict *qdict)
> +void hmp_info_block(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      BlockInfoList *block_list, *info;
>      BlockDeviceInfoList *blockdev_list, *blockdev;
>      const char *device = qdict_get_try_str(qdict, "device");
> @@ -719,8 +742,9 @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
>      qapi_free_BlockDeviceInfoList(blockdev_list);
>  }
>  
> -void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
> +void hmp_info_blockstats(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      BlockStatsList *stats_list, *stats;
>  
>      stats_list = qmp_query_blockstats(false, false, NULL);
> @@ -757,8 +781,9 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
>      qapi_free_BlockStatsList(stats_list);
>  }
>  
> -void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
> +void hmp_info_block_jobs(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      BlockJobInfoList *list;
>  
>      list = qmp_query_block_jobs(&error_abort);
> @@ -793,8 +818,9 @@ void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
>      qapi_free_BlockJobInfoList(list);
>  }
>  
> -void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
> +void hmp_info_snapshots(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      BlockDriverState *bs, *bs1;
>      BdrvNextIterator it1;
>      QEMUSnapshotInfo *sn_tab, *sn;
> diff --git a/chardev/char-hmp-cmds.c b/chardev/char-hmp-cmds.c
> index f377e00b6991..d4a5a3a255a5 100644
> --- a/chardev/char-hmp-cmds.c
> +++ b/chardev/char-hmp-cmds.c
> @@ -24,8 +24,9 @@
>  #include "qemu/config-file.h"
>  #include "qemu/option.h"
>  
> -void hmp_info_chardev(Monitor *mon, const QDict *qdict)
> +void hmp_info_chardev(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      ChardevInfoList *char_info, *info;
>  
>      char_info = qmp_query_chardev(NULL);
> @@ -37,8 +38,9 @@ void hmp_info_chardev(Monitor *mon, const QDict *qdict)
>      qapi_free_ChardevInfoList(char_info);
>  }
>  
> -void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
> +void hmp_ringbuf_write(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *chardev = qdict_get_str(qdict, "device");
>      const char *data = qdict_get_str(qdict, "data");
>      Error *err = NULL;
> @@ -48,8 +50,9 @@ void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
> +void hmp_ringbuf_read(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      uint32_t size = qdict_get_int(qdict, "size");
>      const char *chardev = qdict_get_str(qdict, "device");
>      char *data;
> @@ -77,8 +80,9 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
>      g_free(data);
>  }
>  
> -void hmp_chardev_add(Monitor *mon, const QDict *qdict)
> +void hmp_chardev_add(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *args = qdict_get_str(qdict, "args");
>      Error *err = NULL;
>      QemuOpts *opts;
> @@ -93,8 +97,9 @@ void hmp_chardev_add(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_chardev_change(Monitor *mon, const QDict *qdict)
> +void hmp_chardev_change(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *args = qdict_get_str(qdict, "args");
>      const char *id;
>      Error *err = NULL;
> @@ -127,16 +132,18 @@ end:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
> +void hmp_chardev_remove(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *local_err = NULL;
>  
>      qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
>      hmp_handle_error(mon, local_err);
>  }
>  
> -void hmp_chardev_send_break(Monitor *mon, const QDict *qdict)
> +void hmp_chardev_send_break(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *local_err = NULL;
>  
>      qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err);
> diff --git a/dump/dump-hmp-cmds.c b/dump/dump-hmp-cmds.c
> index 21023db6fd85..ba78ad026f1e 100644
> --- a/dump/dump-hmp-cmds.c
> +++ b/dump/dump-hmp-cmds.c
> @@ -12,8 +12,9 @@
>  #include "qapi/qapi-commands-dump.h"
>  #include "qobject/qdict.h"
>  
> -void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
> +void hmp_dump_guest_memory(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      bool win_dmp = qdict_get_try_bool(qdict, "windmp", false);
>      bool paging = qdict_get_try_bool(qdict, "paging", false);
> @@ -83,8 +84,9 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
>      g_free(prot);
>  }
>  
> -void hmp_info_dump(Monitor *mon, const QDict *qdict)
> +void hmp_info_dump(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      DumpQueryResult *result = qmp_query_dump(NULL);
>  
>      assert(result && result->status < DUMP_STATUS__MAX);
> diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
> index 1c700aad3587..48fa27f12705 100644
> --- a/hw/core/machine-hmp-cmds.c
> +++ b/hw/core/machine-hmp-cmds.c
> @@ -25,8 +25,9 @@
>  #include "system/numa.h"
>  #include "hw/core/boards.h"
>  
> -void hmp_info_cpus(Monitor *mon, const QDict *qdict)
> +void hmp_info_cpus(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      CpuInfoFastList *cpu_list, *cpu;
>  
>      cpu_list = qmp_query_cpus_fast(NULL);
> @@ -48,8 +49,9 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict)
>      qapi_free_CpuInfoFastList(cpu_list);
>  }
>  
> -void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
> +void hmp_hotpluggable_cpus(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      HotpluggableCPUList *l = qmp_query_hotpluggable_cpus(&err);
>      HotpluggableCPUList *saved = l;
> @@ -106,8 +108,9 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
>      qapi_free_HotpluggableCPUList(saved);
>  }
>  
> -void hmp_info_memdev(Monitor *mon, const QDict *qdict)
> +void hmp_info_memdev(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      MemdevList *memdev_list = qmp_query_memdev(&err);
>      MemdevList *m = memdev_list;
> @@ -147,8 +150,9 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_info_kvm(Monitor *mon, const QDict *qdict)
> +void hmp_info_kvm(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      KvmInfo *info;
>  
>      info = qmp_query_kvm(NULL);
> @@ -162,8 +166,9 @@ void hmp_info_kvm(Monitor *mon, const QDict *qdict)
>      qapi_free_KvmInfo(info);
>  }
>  
> -void hmp_info_accelerators(Monitor *mon, const QDict *qdict)
> +void hmp_info_accelerators(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      AcceleratorInfo *info;
>      AcceleratorList *accel;
>  
> @@ -180,8 +185,9 @@ void hmp_info_accelerators(Monitor *mon, const QDict *qdict)
>      qapi_free_AcceleratorInfo(info);
>  }
>  
> -void hmp_info_uuid(Monitor *mon, const QDict *qdict)
> +void hmp_info_uuid(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      UuidInfo *info;
>  
>      info = qmp_query_uuid(NULL);
> @@ -189,8 +195,9 @@ void hmp_info_uuid(Monitor *mon, const QDict *qdict)
>      qapi_free_UuidInfo(info);
>  }
>  
> -void hmp_info_balloon(Monitor *mon, const QDict *qdict)
> +void hmp_info_balloon(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      BalloonInfo *info;
>      Error *err = NULL;
>  
> @@ -204,18 +211,19 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
>      qapi_free_BalloonInfo(info);
>  }
>  
> -void hmp_system_reset(Monitor *mon, const QDict *qdict)
> +void hmp_system_reset(MonitorHMP *hmp, const QDict *qdict)
>  {
>      qmp_system_reset(NULL);
>  }
>  
> -void hmp_system_powerdown(Monitor *mon, const QDict *qdict)
> +void hmp_system_powerdown(MonitorHMP *hmp, const QDict *qdict)
>  {
>      qmp_system_powerdown(NULL);
>  }
>  
> -void hmp_memsave(Monitor *mon, const QDict *qdict)
> +void hmp_memsave(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      uint32_t size = qdict_get_int(qdict, "size");
>      const char *filename = qdict_get_str(qdict, "filename");
>      uint64_t addr = qdict_get_int(qdict, "val");
> @@ -231,8 +239,9 @@ void hmp_memsave(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_pmemsave(Monitor *mon, const QDict *qdict)
> +void hmp_pmemsave(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      uint32_t size = qdict_get_int(qdict, "size");
>      const char *filename = qdict_get_str(qdict, "filename");
>      uint64_t addr = qdict_get_int(qdict, "val");
> @@ -242,24 +251,27 @@ void hmp_pmemsave(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
> +void hmp_system_wakeup(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_system_wakeup(&err);
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_nmi(Monitor *mon, const QDict *qdict)
> +void hmp_nmi(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_inject_nmi(&err);
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_balloon(Monitor *mon, const QDict *qdict)
> +void hmp_balloon(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int64_t value = qdict_get_int(qdict, "value");
>      Error *err = NULL;
>  
> @@ -267,8 +279,9 @@ void hmp_balloon(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
> +void hmp_info_memory_devices(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err);
>      MemoryDeviceInfoList *info;
> @@ -370,8 +383,9 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict)
> +void hmp_info_vm_generation_id(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      GuidInfo *info = qmp_query_vm_generation_id(&err);
>      if (info) {
> @@ -381,8 +395,9 @@ void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict)
>      qapi_free_GuidInfo(info);
>  }
>  
> -void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict)
> +void hmp_info_memory_size_summary(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      MemoryInfo *info = qmp_query_memory_size_summary(&err);
>      if (info) {
> diff --git a/hw/i386/kvm/xen-stubs.c b/hw/i386/kvm/xen-stubs.c
> index bf6ac28bef47..ab1eb14f99e0 100644
> --- a/hw/i386/kvm/xen-stubs.c
> +++ b/hw/i386/kvm/xen-stubs.c
> @@ -40,12 +40,14 @@ void xen_primary_console_set_be_port(uint16_t port)
>  {
>  }
>  
> -void hmp_xen_event_list(Monitor *mon, const QDict *qdict)
> +void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      monitor_printf(mon, "XEN emulation is not available in this QEMU\n");
>  }
>  
> -void hmp_xen_event_inject(Monitor *mon, const QDict *qdict)
> +void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      monitor_printf(mon, "XEN emulation is not available in this QEMU\n");
>  }
> diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c
> index 8b243984e412..845838c372d5 100644
> --- a/hw/i386/kvm/xen_evtchn.c
> +++ b/hw/i386/kvm/xen_evtchn.c
> @@ -2344,8 +2344,9 @@ void qmp_xen_event_inject(uint32_t port, Error **errp)
>      }
>  }
>  
> -void hmp_xen_event_list(Monitor *mon, const QDict *qdict)
> +void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      EvtchnInfoList *iter, *info_list;
>      Error *err = NULL;
>  
> @@ -2379,8 +2380,9 @@ void hmp_xen_event_list(Monitor *mon, const QDict *qdict)
>      qapi_free_EvtchnInfoList(info_list);
>  }
>  
> -void hmp_xen_event_inject(Monitor *mon, const QDict *qdict)
> +void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int port = qdict_get_int(qdict, "port");
>      Error *err = NULL;
>  
> diff --git a/hw/i386/sgx-hmp-stub.c b/hw/i386/sgx-hmp-stub.c
> index cf1d9a6344b0..a4848ae1d1a7 100644
> --- a/hw/i386/sgx-hmp-stub.c
> +++ b/hw/i386/sgx-hmp-stub.c
> @@ -10,7 +10,8 @@
>  #include "monitor/hmp.h"
>  #include "monitor/monitor.h"
>  
> -void hmp_info_sgx(Monitor *mon, const QDict *qdict)
> +void hmp_info_sgx(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      monitor_printf(mon, "SGX is not available in this QEMU\n");
>  }
> diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
> index 7e4c509f5a4a..77b41d234c9f 100644
> --- a/hw/i386/sgx.c
> +++ b/hw/i386/sgx.c
> @@ -234,8 +234,9 @@ SgxInfo *qmp_query_sgx(Error **errp)
>      return info;
>  }
>  
> -void hmp_info_sgx(Monitor *mon, const QDict *qdict)
> +void hmp_info_sgx(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      SgxEpcSectionList *section_list, *section;
>      g_autoptr(SgxInfo) info = qmp_query_sgx(&err);
> diff --git a/hw/misc/mos6522-stub.c b/hw/misc/mos6522-stub.c
> index 85eb0ee36ee1..6a7d76292f00 100644
> --- a/hw/misc/mos6522-stub.c
> +++ b/hw/misc/mos6522-stub.c
> @@ -10,7 +10,8 @@
>  #include "monitor/monitor.h"
>  #include "monitor/hmp.h"
>  
> -void hmp_info_via(Monitor *mon, const QDict *qdict)
> +void hmp_info_via(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      monitor_printf(mon, "MOS6522 VIA is not available in this QEMU\n");
>  }
> diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
> index bae766ef1782..15a6a1a75745 100644
> --- a/hw/misc/mos6522.c
> +++ b/hw/misc/mos6522.c
> @@ -586,8 +586,9 @@ static HumanReadableText *qmp_x_query_via(Error **errp)
>      return human_readable_text_from_str(buf);
>  }
>  
> -void hmp_info_via(Monitor *mon, const QDict *qdict)
> +void hmp_info_via(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      g_autoptr(HumanReadableText) info = qmp_x_query_via(&err);
>  
> diff --git a/hw/net/rocker/rocker-hmp-cmds.c b/hw/net/rocker/rocker-hmp-cmds.c
> index df40991f6d20..856aaef5e210 100644
> --- a/hw/net/rocker/rocker-hmp-cmds.c
> +++ b/hw/net/rocker/rocker-hmp-cmds.c
> @@ -20,8 +20,9 @@
>  #include "qapi/qapi-commands-rocker.h"
>  #include "qobject/qdict.h"
>  
> -void hmp_rocker(Monitor *mon, const QDict *qdict)
> +void hmp_rocker(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *name = qdict_get_str(qdict, "name");
>      RockerSwitch *rocker;
>      Error *err = NULL;
> @@ -38,8 +39,9 @@ void hmp_rocker(Monitor *mon, const QDict *qdict)
>      qapi_free_RockerSwitch(rocker);
>  }
>  
> -void hmp_rocker_ports(Monitor *mon, const QDict *qdict)
> +void hmp_rocker_ports(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      RockerPortList *list, *port;
>      const char *name = qdict_get_str(qdict, "name");
>      Error *err = NULL;
> @@ -65,8 +67,9 @@ void hmp_rocker_ports(Monitor *mon, const QDict *qdict)
>      qapi_free_RockerPortList(list);
>  }
>  
> -void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict)
> +void hmp_rocker_of_dpa_flows(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      RockerOfDpaFlowList *list, *info;
>      const char *name = qdict_get_str(qdict, "name");
>      uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1);
> @@ -214,8 +217,9 @@ void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict)
>      qapi_free_RockerOfDpaFlowList(list);
>  }
>  
> -void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict)
> +void hmp_rocker_of_dpa_groups(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      RockerOfDpaGroupList *list, *g;
>      const char *name = qdict_get_str(qdict, "name");
>      uint8_t type = qdict_get_try_int(qdict, "type", 9);
> diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c
> index a5f6483cc3d2..be24aecc8ac8 100644
> --- a/hw/pci/pci-hmp-cmds.c
> +++ b/hw/pci/pci-hmp-cmds.c
> @@ -117,8 +117,9 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
>      }
>  }
>  
> -void hmp_info_pci(Monitor *mon, const QDict *qdict)
> +void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      PciInfoList *info_list, *info;
>  
>      info_list = qmp_query_pci(&error_abort);
> @@ -170,8 +171,9 @@ void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
>      }
>  }
>  
> -void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict)
> +void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *id = qdict_get_str(qdict, "id");
>      const char *error_name;
> diff --git a/hw/pci/pci-stub.c b/hw/pci/pci-stub.c
> index 3397d0c82ea8..a80e34175462 100644
> --- a/hw/pci/pci-stub.c
> +++ b/hw/pci/pci-stub.c
> @@ -34,12 +34,13 @@ PciInfoList *qmp_query_pci(Error **errp)
>      return NULL;
>  }
>  
> -void hmp_info_pci(Monitor *mon, const QDict *qdict)
> +void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict)
>  {
>  }
>  
> -void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict)
> +void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      monitor_printf(mon, "PCI devices not supported\n");
>  }
>  
> diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
> index 7dca67d6618c..d8afaf730639 100644
> --- a/hw/s390x/s390-skeys.c
> +++ b/hw/s390x/s390-skeys.c
> @@ -104,8 +104,9 @@ static void write_keys(FILE *f, uint8_t *keys, uint64_t startgfn,
>      }
>  }
>  
> -void hmp_info_skeys(Monitor *mon, const QDict *qdict)
> +void hmp_info_skeys(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      S390SKeysState *ss = s390_get_skeys_device();
>      S390SKeysClass *skeyclass = S390_SKEYS_GET_CLASS(ss);
>      uint64_t addr = qdict_get_int(qdict, "addr");
> @@ -134,7 +135,7 @@ void hmp_info_skeys(Monitor *mon, const QDict *qdict)
>      monitor_printf(mon, "  key: 0x%X\n", key);
>  }
>  
> -void hmp_dump_skeys(Monitor *mon, const QDict *qdict)
> +void hmp_dump_skeys(MonitorHMP *hmp, const QDict *qdict)
>  {
>      const char *filename = qdict_get_str(qdict, "filename");
>      Error *err = NULL;
> diff --git a/hw/s390x/s390-stattrib.c b/hw/s390x/s390-stattrib.c
> index b0f04eb30c7f..b4a405455901 100644
> --- a/hw/s390x/s390-stattrib.c
> +++ b/hw/s390x/s390-stattrib.c
> @@ -59,8 +59,9 @@ void s390_stattrib_init(void)
>  
>  /* Console commands: */
>  
> -void hmp_migrationmode(Monitor *mon, const QDict *qdict)
> +void hmp_migrationmode(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      S390StAttribState *sas = s390_get_stattrib_device();
>      S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
>      uint64_t what = qdict_get_int(qdict, "mode");
> @@ -74,8 +75,9 @@ void hmp_migrationmode(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_info_cmma(Monitor *mon, const QDict *qdict)
> +void hmp_info_cmma(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      S390StAttribState *sas = s390_get_stattrib_device();
>      S390StAttribClass *sac = S390_STATTRIB_GET_CLASS(sas);
>      uint64_t addr = qdict_get_int(qdict, "addr");
> diff --git a/hw/uefi/ovmf-log.c b/hw/uefi/ovmf-log.c
> index 3a24afd9417d..c97622b2aad6 100644
> --- a/hw/uefi/ovmf-log.c
> +++ b/hw/uefi/ovmf-log.c
> @@ -256,8 +256,9 @@ FirmwareLog *qmp_query_firmware_log(bool have_max_size, uint64_t max_size,
>      return ret;
>  }
>  
> -void hmp_info_firmware_log(Monitor *mon, const QDict *qdict)
> +void hmp_info_firmware_log(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      g_autofree gchar *log_esc = NULL;
>      g_autofree guchar *log_out = NULL;
>      Error *err = NULL;
> diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
> index af67d5dfeb10..c02343d3a655 100644
> --- a/hw/usb/host-libusb.c
> +++ b/hw/usb/host-libusb.c
> @@ -1920,8 +1920,9 @@ static void usb_host_auto_check(void *unused)
>      timer_mod(usb_auto_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 2000);
>  }
>  
> -void hmp_info_usbhost(Monitor *mon, const QDict *qdict)
> +void hmp_info_usbhost(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      libusb_device **devs = NULL;
>      struct libusb_device_descriptor ddesc;
>      char port[16];
> diff --git a/hw/virtio/virtio-hmp-cmds.c b/hw/virtio/virtio-hmp-cmds.c
> index a91bb7dbeda5..49f3367785ba 100644
> --- a/hw/virtio/virtio-hmp-cmds.c
> +++ b/hw/virtio/virtio-hmp-cmds.c
> @@ -80,8 +80,9 @@ static void hmp_virtio_dump_features(Monitor *mon,
>      }
>  }
>  
> -void hmp_virtio_query(Monitor *mon, const QDict *qdict)
> +void hmp_virtio_query(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      VirtioInfoList *list = qmp_x_query_virtio(&err);
>      VirtioInfoList *node;
> @@ -105,8 +106,9 @@ void hmp_virtio_query(Monitor *mon, const QDict *qdict)
>      qapi_free_VirtioInfoList(list);
>  }
>  
> -void hmp_virtio_status(Monitor *mon, const QDict *qdict)
> +void hmp_virtio_status(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *path = qdict_get_try_str(qdict, "path");
>      VirtioStatus *s = qmp_x_query_virtio_status(path, &err);
> @@ -183,8 +185,9 @@ void hmp_virtio_status(Monitor *mon, const QDict *qdict)
>      qapi_free_VirtioStatus(s);
>  }
>  
> -void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict)
> +void hmp_vhost_queue_status(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *path = qdict_get_try_str(qdict, "path");
>      int queue = qdict_get_int(qdict, "queue");
> @@ -216,8 +219,9 @@ void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict)
>      qapi_free_VirtVhostQueueStatus(s);
>  }
>  
> -void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict)
> +void hmp_virtio_queue_status(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *path = qdict_get_try_str(qdict, "path");
>      int queue = qdict_get_int(qdict, "queue");
> @@ -261,8 +265,9 @@ void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict)
>      qapi_free_VirtQueueStatus(s);
>  }
>  
> -void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict)
> +void hmp_virtio_queue_element(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *path = qdict_get_try_str(qdict, "path");
>      int queue = qdict_get_int(qdict, "queue");
> diff --git a/include/block/block-hmp-cmds.h b/include/block/block-hmp-cmds.h
> index 71113cd7efa4..0f5908958f05 100644
> --- a/include/block/block-hmp-cmds.h
> +++ b/include/block/block-hmp-cmds.h
> @@ -16,41 +16,42 @@
>  #define BLOCK_BLOCK_HMP_CMDS_H
>  
>  #include "qemu/coroutine.h"
> +#include "monitor/hmp.h"
>  
> -void hmp_drive_add(Monitor *mon, const QDict *qdict);
> +void hmp_drive_add(MonitorHMP *hmp, const QDict *qdict);
>  
> -void hmp_commit(Monitor *mon, const QDict *qdict);
> -void hmp_drive_del(Monitor *mon, const QDict *qdict);
> +void hmp_commit(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_drive_del(MonitorHMP *hmp, const QDict *qdict);
>  
> -void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
> -void hmp_drive_backup(Monitor *mon, const QDict *qdict);
> +void hmp_drive_mirror(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_drive_backup(MonitorHMP *hmp, const QDict *qdict);
>  
> -void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
> -void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
> -void hmp_block_job_pause(Monitor *mon, const QDict *qdict);
> -void hmp_block_job_resume(Monitor *mon, const QDict *qdict);
> -void hmp_block_job_complete(Monitor *mon, const QDict *qdict);
> +void hmp_block_job_set_speed(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_block_job_cancel(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_block_job_pause(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_block_job_resume(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_block_job_complete(MonitorHMP *hmp, const QDict *qdict);
>  
> -void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
> -void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict);
> -void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict);
> +void hmp_snapshot_blkdev(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_snapshot_blkdev_internal(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_snapshot_delete_blkdev_internal(MonitorHMP *hmp, const QDict *qdict);
>  
> -void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
> -void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
> -void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict);
> -void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
> +void hmp_nbd_server_start(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_nbd_server_add(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_nbd_server_remove(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_nbd_server_stop(MonitorHMP *hmp, const QDict *qdict);
>  
> -void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict);
> -void hmp_block_stream(Monitor *mon, const QDict *qdict);
> -void hmp_block_passwd(Monitor *mon, const QDict *qdict);
> -void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict);
> -void hmp_eject(Monitor *mon, const QDict *qdict);
> +void coroutine_fn hmp_block_resize(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_block_stream(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_block_passwd(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_block_set_io_throttle(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_eject(MonitorHMP *hmp, const QDict *qdict);
>  
> -void hmp_qemu_io(Monitor *mon, const QDict *qdict);
> +void hmp_qemu_io(MonitorHMP *hmp, const QDict *qdict);
>  
> -void hmp_info_block(Monitor *mon, const QDict *qdict);
> -void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
> -void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
> -void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
> +void hmp_info_block(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_blockstats(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_block_jobs(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_snapshots(MonitorHMP *hmp, const QDict *qdict);
>  
>  #endif
> diff --git a/include/hw/usb/usb.h b/include/hw/usb/usb.h
> index 78e2ceedd7fd..cbd4711933e8 100644
> --- a/include/hw/usb/usb.h
> +++ b/include/hw/usb/usb.h
> @@ -31,6 +31,7 @@
>  #include "qemu/queue.h"
>  #include "qom/object.h"
>  #include "qapi/error.h"
> +#include "monitor/hmp.h"
>  
>  /* Constants related to the USB / PCI interaction */
>  #define USB_SBRN    0x60 /* Serial Bus Release Number Register */
> @@ -466,7 +467,7 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream);
>  void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p);
>  
>  /* usb-linux.c */
> -void hmp_info_usbhost(Monitor *mon, const QDict *qdict);
> +void hmp_info_usbhost(MonitorHMP *hmp, const QDict *qdict);
>  
>  /* usb ports of the VM */
>  
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index 166cd4100c63..7a270ad3f25c 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -22,7 +22,7 @@
>  OBJECT_DECLARE_TYPE(MonitorHMP, MonitorHMPClass, MONITOR_HMP);
>  
>  #define HMP_STUB(cmd) \
> -    void hmp_##cmd(Monitor *mon, const QDict *qdict) \
> +    void hmp_##cmd(MonitorHMP *hmp, const QDict *qdict) \
>      { \
>          g_assert_not_reached(); \
>      }
> @@ -46,7 +46,7 @@ int monitor_hmp_read_password(MonitorHMP *hmp, ReadLineFunc *readline_func,
>                                void *opaque);
>  
>  void monitor_register_hmp(const char *name, bool info,
> -                          void (*cmd)(Monitor *mon, const QDict *qdict));
> +                          void (*cmd)(MonitorHMP *mon, const QDict *qdict));
>  void monitor_register_hmp_info_hrt(const char *name,
>                                     HumanReadableText *(*handler)(Error **errp));
>  
> @@ -58,58 +58,58 @@ bool hmp_handle_error(Monitor *mon, Error *err);
>  void hmp_help_cmd(Monitor *mon, const char *name);
>  strList *hmp_split_at_comma(const char *str);
>  
> -void hmp_info_name(Monitor *mon, const QDict *qdict);
> -void hmp_info_version(Monitor *mon, const QDict *qdict);
> -void hmp_info_kvm(Monitor *mon, const QDict *qdict);
> -void hmp_info_accelerators(Monitor *mon, const QDict *qdict);
> -void hmp_info_status(Monitor *mon, const QDict *qdict);
> -void hmp_info_uuid(Monitor *mon, const QDict *qdict);
> -void hmp_info_chardev(Monitor *mon, const QDict *qdict);
> -void hmp_info_mice(Monitor *mon, const QDict *qdict);
> -void hmp_info_migrate(Monitor *mon, const QDict *qdict);
> -void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
> -void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict);
> -void hmp_info_cpus(Monitor *mon, const QDict *qdict);
> -void hmp_info_vnc(Monitor *mon, const QDict *qdict);
> -void hmp_info_spice(Monitor *mon, const QDict *qdict);
> -void hmp_info_balloon(Monitor *mon, const QDict *qdict);
> -void hmp_info_pci(Monitor *mon, const QDict *qdict);
> -void hmp_info_tpm(Monitor *mon, const QDict *qdict);
> -void hmp_info_iothreads(Monitor *mon, const QDict *qdict);
> -void hmp_quit(Monitor *mon, const QDict *qdict);
> -void hmp_stop(Monitor *mon, const QDict *qdict);
> -void hmp_sync_profile(Monitor *mon, const QDict *qdict);
> -void hmp_system_reset(Monitor *mon, const QDict *qdict);
> -void hmp_system_powerdown(Monitor *mon, const QDict *qdict);
> -void hmp_exit_preconfig(Monitor *mon, const QDict *qdict);
> -void hmp_announce_self(Monitor *mon, const QDict *qdict);
> -void hmp_cpu(Monitor *mon, const QDict *qdict);
> -void hmp_memsave(Monitor *mon, const QDict *qdict);
> -void hmp_pmemsave(Monitor *mon, const QDict *qdict);
> -void hmp_ringbuf_write(Monitor *mon, const QDict *qdict);
> -void hmp_ringbuf_read(Monitor *mon, const QDict *qdict);
> -void hmp_cont(Monitor *mon, const QDict *qdict);
> -void hmp_system_wakeup(Monitor *mon, const QDict *qdict);
> -void hmp_nmi(Monitor *mon, const QDict *qdict);
> -void hmp_info_network(Monitor *mon, const QDict *qdict);
> -void hmp_set_link(Monitor *mon, const QDict *qdict);
> -void hmp_balloon(Monitor *mon, const QDict *qdict);
> -void hmp_loadvm(Monitor *mon, const QDict *qdict);
> -void hmp_savevm(Monitor *mon, const QDict *qdict);
> -void hmp_delvm(Monitor *mon, const QDict *qdict);
> -void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
> -void hmp_migrate_continue(Monitor *mon, const QDict *qdict);
> -void hmp_migrate_incoming(Monitor *mon, const QDict *qdict);
> -void hmp_migrate_recover(Monitor *mon, const QDict *qdict);
> -void hmp_migrate_pause(Monitor *mon, const QDict *qdict);
> -void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict);
> -void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict);
> -void hmp_client_migrate_info(Monitor *mon, const QDict *qdict);
> -void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict);
> -void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict);
> -void hmp_set_password(Monitor *mon, const QDict *qdict);
> -void hmp_expire_password(Monitor *mon, const QDict *qdict);
> -void hmp_change(Monitor *mon, const QDict *qdict);
> +void hmp_info_name(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_version(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_kvm(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_accelerators(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_status(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_uuid(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_chardev(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_mice(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_migrate(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_migrate_capabilities(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_migrate_parameters(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_cpus(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_vnc(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_spice(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_balloon(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_pci(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_tpm(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_iothreads(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_quit(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_stop(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_sync_profile(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_system_reset(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_system_powerdown(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_exit_preconfig(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_announce_self(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_cpu(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_memsave(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_pmemsave(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_ringbuf_write(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_ringbuf_read(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_cont(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_system_wakeup(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_nmi(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_network(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_set_link(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_balloon(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_loadvm(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_savevm(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_delvm(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_migrate_cancel(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_migrate_continue(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_migrate_incoming(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_migrate_recover(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_migrate_pause(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_migrate_set_capability(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_migrate_set_parameter(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_client_migrate_info(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_migrate_start_postcopy(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_x_colo_lost_heartbeat(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_set_password(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_expire_password(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_change(MonitorHMP *hmp, const QDict *qdict);
>  #ifdef CONFIG_VNC
>  void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
>                      const char *arg, const char *read_only, bool force,
> @@ -118,101 +118,101 @@ void hmp_change_vnc(Monitor *mon, const char *device, const char *target,
>  void hmp_change_medium(Monitor *mon, const char *device, const char *target,
>                         const char *arg, const char *read_only, bool force,
>                         Error **errp);
> -void hmp_migrate(Monitor *mon, const QDict *qdict);
> -void hmp_device_add(Monitor *mon, const QDict *qdict);
> -void hmp_device_del(Monitor *mon, const QDict *qdict);
> -void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
> -void hmp_netdev_add(Monitor *mon, const QDict *qdict);
> -void hmp_netdev_del(Monitor *mon, const QDict *qdict);
> -void hmp_getfd(Monitor *mon, const QDict *qdict);
> -void hmp_closefd(Monitor *mon, const QDict *qdict);
> -void hmp_mouse_move(Monitor *mon, const QDict *qdict);
> -void hmp_mouse_button(Monitor *mon, const QDict *qdict);
> -void hmp_mouse_set(Monitor *mon, const QDict *qdict);
> -void hmp_sendkey(Monitor *mon, const QDict *qdict);
> -void coroutine_fn hmp_screendump(Monitor *mon, const QDict *qdict);
> -void hmp_chardev_add(Monitor *mon, const QDict *qdict);
> -void hmp_chardev_change(Monitor *mon, const QDict *qdict);
> -void hmp_chardev_remove(Monitor *mon, const QDict *qdict);
> -void hmp_chardev_send_break(Monitor *mon, const QDict *qdict);
> -void hmp_object_add(Monitor *mon, const QDict *qdict);
> -void hmp_object_del(Monitor *mon, const QDict *qdict);
> -void hmp_info_memdev(Monitor *mon, const QDict *qdict);
> -void hmp_info_memory_devices(Monitor *mon, const QDict *qdict);
> -void hmp_qom_list(Monitor *mon, const QDict *qdict);
> -void hmp_qom_get(Monitor *mon, const QDict *qdict);
> -void hmp_qom_set(Monitor *mon, const QDict *qdict);
> -void hmp_info_qom_tree(Monitor *mon, const QDict *dict);
> -void hmp_virtio_query(Monitor *mon, const QDict *qdict);
> -void hmp_virtio_status(Monitor *mon, const QDict *qdict);
> -void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict);
> -void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict);
> -void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict);
> -void hmp_xen_event_inject(Monitor *mon, const QDict *qdict);
> -void hmp_xen_event_list(Monitor *mon, const QDict *qdict);
> -void hmp_rocker(Monitor *mon, const QDict *qdict);
> -void hmp_rocker_ports(Monitor *mon, const QDict *qdict);
> -void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict);
> -void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict);
> -void hmp_info_dump(Monitor *mon, const QDict *qdict);
> -void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict);
> -void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict);
> -void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict);
> -void hmp_info_replay(Monitor *mon, const QDict *qdict);
> -void hmp_replay_break(Monitor *mon, const QDict *qdict);
> -void hmp_replay_delete_break(Monitor *mon, const QDict *qdict);
> -void hmp_replay_seek(Monitor *mon, const QDict *qdict);
> -void hmp_info_dirty_rate(Monitor *mon, const QDict *qdict);
> -void hmp_calc_dirty_rate(Monitor *mon, const QDict *qdict);
> -void hmp_set_vcpu_dirty_limit(Monitor *mon, const QDict *qdict);
> -void hmp_cancel_vcpu_dirty_limit(Monitor *mon, const QDict *qdict);
> -void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict *qdict);
> +void hmp_migrate(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_device_add(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_device_del(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_dump_guest_memory(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_netdev_add(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_netdev_del(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_getfd(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_closefd(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_mouse_move(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_mouse_button(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_mouse_set(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_sendkey(MonitorHMP *hmp, const QDict *qdict);
> +void coroutine_fn hmp_screendump(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_chardev_add(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_chardev_change(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_chardev_remove(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_chardev_send_break(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_object_add(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_object_del(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_memdev(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_memory_devices(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_qom_list(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_qom_get(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_qom_set(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_qom_tree(MonitorHMP *hmp, const QDict *dict);
> +void hmp_virtio_query(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_virtio_status(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_virtio_queue_status(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_vhost_queue_status(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_virtio_queue_element(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_rocker(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_rocker_ports(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_rocker_of_dpa_flows(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_rocker_of_dpa_groups(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_dump(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_hotpluggable_cpus(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_vm_generation_id(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_memory_size_summary(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_replay(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_replay_break(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_replay_delete_break(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_replay_seek(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_dirty_rate(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_calc_dirty_rate(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_set_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_cancel_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict);
>  void hmp_human_readable_text_helper(Monitor *mon,
>                                      HumanReadableText *(*qmp_handler)(Error **));
> -void hmp_info_stats(Monitor *mon, const QDict *qdict);
> -void hmp_one_insn_per_tb(Monitor *mon, const QDict *qdict);
> -void hmp_watchdog_action(Monitor *mon, const QDict *qdict);
> -void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict);
> -void hmp_info_capture(Monitor *mon, const QDict *qdict);
> -void hmp_stopcapture(Monitor *mon, const QDict *qdict);
> -void hmp_wavcapture(Monitor *mon, const QDict *qdict);
> -void hmp_trace_event(Monitor *mon, const QDict *qdict);
> -void hmp_trace_file(Monitor *mon, const QDict *qdict);
> -void hmp_info_trace_events(Monitor *mon, const QDict *qdict);
> -void hmp_help(Monitor *mon, const QDict *qdict);
> -void hmp_clear(Monitor *mon, const QDict *qdict);
> -void hmp_info_help(Monitor *mon, const QDict *qdict);
> -void hmp_info_sync_profile(Monitor *mon, const QDict *qdict);
> -void hmp_info_history(Monitor *mon, const QDict *qdict);
> -void hmp_logfile(Monitor *mon, const QDict *qdict);
> -void hmp_log(Monitor *mon, const QDict *qdict);
> -void hmp_gdbserver(Monitor *mon, const QDict *qdict);
> -void hmp_print(Monitor *mon, const QDict *qdict);
> -void hmp_sum(Monitor *mon, const QDict *qdict);
> -void hmp_ioport_read(Monitor *mon, const QDict *qdict);
> -void hmp_ioport_write(Monitor *mon, const QDict *qdict);
> -void hmp_boot_set(Monitor *mon, const QDict *qdict);
> -void hmp_info_mtree(Monitor *mon, const QDict *qdict);
> -void hmp_info_cryptodev(Monitor *mon, const QDict *qdict);
> -void hmp_dumpdtb(Monitor *mon, const QDict *qdict);
> -void hmp_info_firmware_log(Monitor *mon, const QDict *qdict);
> -void hmp_info_mem(Monitor *mon, const QDict *qdict);
> -void hmp_info_tlb(Monitor *mon, const QDict *qdict);
> -void hmp_mce(Monitor *mon, const QDict *qdict);
> -void hmp_info_local_apic(Monitor *mon, const QDict *qdict);
> -void hmp_info_sev(Monitor *mon, const QDict *qdict);
> -void hmp_info_sgx(Monitor *mon, const QDict *qdict);
> -void hmp_info_via(Monitor *mon, const QDict *qdict);
> -void hmp_memory_dump(Monitor *mon, const QDict *qdict);
> -void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict);
> -void hmp_info_registers(Monitor *mon, const QDict *qdict);
> -void hmp_gva2gpa(Monitor *mon, const QDict *qdict);
> -void hmp_gpa2hva(Monitor *mon, const QDict *qdict);
> -void hmp_gpa2hpa(Monitor *mon, const QDict *qdict);
> +void hmp_info_stats(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_one_insn_per_tb(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_watchdog_action(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_capture(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_stopcapture(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_wavcapture(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_trace_event(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_trace_file(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_trace_events(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_help(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_clear(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_help(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_sync_profile(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_history(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_logfile(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_log(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_gdbserver(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_print(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_sum(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_ioport_read(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_ioport_write(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_boot_set(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_mtree(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_cryptodev(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_dumpdtb(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_firmware_log(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_mce(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_local_apic(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_sev(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_sgx(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_via(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_memory_dump(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_physical_memory_dump(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_registers(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_gva2gpa(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_gpa2hva(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_gpa2hpa(MonitorHMP *hmp, const QDict *qdict);
>  
> -void hmp_dump_skeys(Monitor *mon, const QDict *qdict);
> -void hmp_info_skeys(Monitor *mon, const QDict *qdict);
> -void hmp_info_cmma(Monitor *mon, const QDict *qdict);
> -void hmp_migrationmode(Monitor *mon, const QDict *qdict);
> +void hmp_dump_skeys(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_skeys(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_cmma(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_migrationmode(MonitorHMP *hmp, const QDict *qdict);
>  
>  #endif
> diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h
> index f85f25738d58..8f7e2f616cf3 100644
> --- a/include/monitor/qdev.h
> +++ b/include/monitor/qdev.h
> @@ -2,11 +2,12 @@
>  #define MONITOR_QDEV_H
>  
>  #include "hw/core/qdev.h"
> +#include "monitor/hmp.h"
>  
>  /*** monitor commands ***/
>  
> -void hmp_info_qtree(Monitor *mon, const QDict *qdict);
> -void hmp_info_qdm(Monitor *mon, const QDict *qdict);
> +void hmp_info_qtree(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_info_qdm(MonitorHMP *hmp, const QDict *qdict);
>  void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp);
>  
>  int qdev_device_help(QemuOpts *opts);
> diff --git a/include/net/net.h b/include/net/net.h
> index a7c49c543783..626b99794806 100644
> --- a/include/net/net.h
> +++ b/include/net/net.h
> @@ -5,6 +5,7 @@
>  #include "qapi/qapi-types-net.h"
>  #include "net/queue.h"
>  #include "hw/core/qdev-properties-system.h"
> +#include "monitor/hmp.h"
>  
>  #define MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
>  #define MAC_ARG(x) ((uint8_t *)(x))[0], ((uint8_t *)(x))[1], \
> @@ -318,8 +319,8 @@ void net_init_clients(void);
>  void net_check_clients(void);
>  void net_client_set_link(NetClientState **ncs, int queues, bool up);
>  void net_cleanup(void);
> -void hmp_host_net_add(Monitor *mon, const QDict *qdict);
> -void hmp_host_net_remove(Monitor *mon, const QDict *qdict);
> +void hmp_host_net_add(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_host_net_remove(MonitorHMP *hmp, const QDict *qdict);
>  void netdev_add(QemuOpts *opts, Error **errp);
>  
>  int net_hub_id_for_client(NetClientState *nc, int *id);
> diff --git a/include/net/slirp.h b/include/net/slirp.h
> index bad3e1e2416b..38859edf58ae 100644
> --- a/include/net/slirp.h
> +++ b/include/net/slirp.h
> @@ -24,13 +24,13 @@
>  #ifndef QEMU_NET_SLIRP_H
>  #define QEMU_NET_SLIRP_H
>  
> -
>  #ifdef CONFIG_SLIRP
> +#include "monitor/hmp.h"
>  
> -void hmp_hostfwd_add(Monitor *mon, const QDict *qdict);
> -void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict);
> +void hmp_hostfwd_add(MonitorHMP *hmp, const QDict *qdict);
> +void hmp_hostfwd_remove(MonitorHMP *hmp, const QDict *qdict);
>  
> -void hmp_info_usernet(Monitor *mon, const QDict *qdict);
> +void hmp_info_usernet(MonitorHMP *hmp, const QDict *qdict);
>  
>  #endif
>  
> diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
> index b360f49efeaf..567abab321cc 100644
> --- a/migration/dirtyrate.c
> +++ b/migration/dirtyrate.c
> @@ -856,8 +856,9 @@ struct DirtyRateInfo *qmp_query_dirty_rate(bool has_calc_time_unit,
>          has_calc_time_unit ? calc_time_unit : TIME_UNIT_SECOND);
>  }
>  
> -void hmp_info_dirty_rate(Monitor *mon, const QDict *qdict)
> +void hmp_info_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      DirtyRateInfo *info = query_dirty_rate_info(TIME_UNIT_SECOND);
>  
>      monitor_printf(mon, "Status: %s\n",
> @@ -891,8 +892,9 @@ void hmp_info_dirty_rate(Monitor *mon, const QDict *qdict)
>      g_free(info);
>  }
>  
> -void hmp_calc_dirty_rate(Monitor *mon, const QDict *qdict)
> +void hmp_calc_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int64_t sec = qdict_get_try_int(qdict, "second", 0);
>      int64_t sample_pages = qdict_get_try_int(qdict, "sample_pages_per_GB", -1);
>      bool has_sample_pages = (sample_pages != -1);
> diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c
> index ad68fa23aa4b..8d2e8735277e 100644
> --- a/migration/migration-hmp-cmds.c
> +++ b/migration/migration-hmp-cmds.c
> @@ -135,8 +135,9 @@ static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info)
>      }
>  }
>  
> -void hmp_info_migrate(Monitor *mon, const QDict *qdict)
> +void hmp_info_migrate(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      bool show_all = qdict_get_try_bool(qdict, "all", false);
>      MigrationInfo *info;
>  
> @@ -297,8 +298,9 @@ out:
>      qapi_free_MigrationInfo(info);
>  }
>  
> -void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict)
> +void hmp_info_migrate_capabilities(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      MigrationCapabilityStatusList *caps, *cap;
>  
>      caps = qmp_query_migrate_capabilities(NULL);
> @@ -326,8 +328,9 @@ static void monitor_print_cpr_exec_command(Monitor *mon, strList *args)
>      monitor_printf(mon, "\n");
>  }
>  
> -void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
> +void hmp_info_migrate_parameters(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      MigrationParameters *params;
>      MigrationState *s = migrate_get_current();
>  
> @@ -473,8 +476,9 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
>      qapi_free_MigrationParameters(params);
>  }
>  
> -void hmp_loadvm(Monitor *mon, const QDict *qdict)
> +void hmp_loadvm(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      RunState saved_state = runstate_get();
>  
>      const char *name = qdict_get_str(qdict, "name");
> @@ -489,8 +493,9 @@ void hmp_loadvm(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_savevm(Monitor *mon, const QDict *qdict)
> +void hmp_savevm(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      save_snapshot(qdict_get_try_str(qdict, "name"),
> @@ -498,8 +503,9 @@ void hmp_savevm(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_delvm(Monitor *mon, const QDict *qdict)
> +void hmp_delvm(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *name = qdict_get_str(qdict, "name");
>  
> @@ -507,13 +513,14 @@ void hmp_delvm(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
> +void hmp_migrate_cancel(MonitorHMP *hmp, const QDict *qdict)
>  {
>      qmp_migrate_cancel(NULL);
>  }
>  
> -void hmp_migrate_continue(Monitor *mon, const QDict *qdict)
> +void hmp_migrate_continue(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *state = qdict_get_str(qdict, "state");
>      int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err);
> @@ -525,8 +532,9 @@ void hmp_migrate_continue(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
> +void hmp_migrate_incoming(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *uri = qdict_get_str(qdict, "uri");
>      MigrationChannelList *caps = NULL;
> @@ -544,8 +552,9 @@ end:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_migrate_recover(Monitor *mon, const QDict *qdict)
> +void hmp_migrate_recover(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *uri = qdict_get_str(qdict, "uri");
>  
> @@ -554,8 +563,9 @@ void hmp_migrate_recover(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_migrate_pause(Monitor *mon, const QDict *qdict)
> +void hmp_migrate_pause(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_migrate_pause(&err);
> @@ -564,8 +574,9 @@ void hmp_migrate_pause(Monitor *mon, const QDict *qdict)
>  }
>  
>  
> -void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
> +void hmp_migrate_set_capability(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *cap = qdict_get_str(qdict, "capability");
>      bool state = qdict_get_bool(qdict, "state");
>      Error *err = NULL;
> @@ -589,8 +600,9 @@ end:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
> +void hmp_migrate_set_parameter(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *param = qdict_get_str(qdict, "parameter");
>      const char *valuestr = qdict_get_str(qdict, "value");
>      Visitor *v = string_input_visitor_new(valuestr);
> @@ -790,16 +802,18 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict)
> +void hmp_migrate_start_postcopy(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      qmp_migrate_start_postcopy(&err);
>      hmp_handle_error(mon, err);
>  }
>  
>  #ifdef CONFIG_REPLICATION
> -void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict)
> +void hmp_x_colo_lost_heartbeat(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_x_colo_lost_heartbeat(&err);
> @@ -833,8 +847,9 @@ static void hmp_migrate_status_cb(void *opaque)
>      qapi_free_MigrationInfo(info);
>  }
>  
> -void hmp_migrate(Monitor *mon, const QDict *qdict)
> +void hmp_migrate(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      bool detach = qdict_get_try_bool(qdict, "detach", false);
>      bool resume = qdict_get_try_bool(qdict, "resume", false);
>      const char *uri = qdict_get_str(qdict, "uri");
> @@ -873,7 +888,6 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)
>  
>      if (!detach) {
>          HMPMigrationStatus *status;
> -        MonitorHMP *hmp = MONITOR_HMP(mon);
>  
>          if (!hmp->use_readline) {
>              monitor_printf(mon, "terminal does not allow synchronous "
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index 6718fec97047..afe4817b4056 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -103,8 +103,9 @@ strList *hmp_split_at_comma(const char *str)
>      return res;
>  }
>  
> -void hmp_info_name(Monitor *mon, const QDict *qdict)
> +void hmp_info_name(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      NameInfo *info;
>  
>      info = qmp_query_name(NULL);
> @@ -114,8 +115,9 @@ void hmp_info_name(Monitor *mon, const QDict *qdict)
>      qapi_free_NameInfo(info);
>  }
>  
> -void hmp_info_version(Monitor *mon, const QDict *qdict)
> +void hmp_info_version(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      VersionInfo *info;
>  
>      info = qmp_query_version(NULL);
> @@ -127,22 +129,23 @@ void hmp_info_version(Monitor *mon, const QDict *qdict)
>      qapi_free_VersionInfo(info);
>  }
>  
> -void hmp_quit(Monitor *mon, const QDict *qdict)
> +void hmp_quit(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    MonitorHMP *hmp = MONITOR_HMP(mon);
> +    Monitor *mon = MONITOR(hmp);
>      if (hmp->use_readline) {
>          monitor_suspend(mon);
>      }
>      qmp_quit(NULL);
>  }
>  
> -void hmp_stop(Monitor *mon, const QDict *qdict)
> +void hmp_stop(MonitorHMP *hmp, const QDict *qdict)
>  {
>      qmp_stop(NULL);
>  }
>  
> -void hmp_sync_profile(Monitor *mon, const QDict *qdict)
> +void hmp_sync_profile(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *op = qdict_get_try_str(qdict, "op");
>  
>      if (op == NULL) {
> @@ -166,16 +169,18 @@ void hmp_sync_profile(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_exit_preconfig(Monitor *mon, const QDict *qdict)
> +void hmp_exit_preconfig(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_x_exit_preconfig(&err);
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_cpu(Monitor *mon, const QDict *qdict)
> +void hmp_cpu(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int64_t cpu_index;
>  
>      /* XXX: drop the monitor_set_cpu() usage when all HMP commands that
> @@ -186,16 +191,18 @@ void hmp_cpu(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_cont(Monitor *mon, const QDict *qdict)
> +void hmp_cont(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_cont(&err);
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_change(Monitor *mon, const QDict *qdict)
> +void hmp_change(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *target = qdict_get_str(qdict, "target");
>      const char *arg = qdict_get_try_str(qdict, "arg");
> @@ -216,8 +223,9 @@ void hmp_change(Monitor *mon, const QDict *qdict)
>  }
>  
>  #ifdef CONFIG_POSIX
> -void hmp_getfd(Monitor *mon, const QDict *qdict)
> +void hmp_getfd(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *fdname = qdict_get_str(qdict, "fdname");
>      Error *err = NULL;
>  
> @@ -226,8 +234,9 @@ void hmp_getfd(Monitor *mon, const QDict *qdict)
>  }
>  #endif
>  
> -void hmp_closefd(Monitor *mon, const QDict *qdict)
> +void hmp_closefd(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *fdname = qdict_get_str(qdict, "fdname");
>      Error *err = NULL;
>  
> @@ -235,8 +244,9 @@ void hmp_closefd(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
> +void hmp_info_iothreads(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
>      IOThreadInfoList *info;
>      IOThreadInfo *value;
> @@ -256,13 +266,15 @@ void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
>      qapi_free_IOThreadInfoList(info_list);
>  }
>  
> -void hmp_help(Monitor *mon, const QDict *qdict)
> +void hmp_help(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      hmp_help_cmd(mon, qdict_get_try_str(qdict, "name"));
>  }
>  
> -void hmp_clear(Monitor *mon, const QDict *qdict)
> +void hmp_clear(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      /*
>       * Send an ANSI escape sequence:
>       * "\x1b[H" - move cursor to top-left
> @@ -272,12 +284,13 @@ void hmp_clear(Monitor *mon, const QDict *qdict)
>      monitor_printf(mon, "\x1b[H\x1b[2J\x1b[3J");
>  }
>  
> -void hmp_info_help(Monitor *mon, const QDict *qdict)
> +void hmp_info_help(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      hmp_help_cmd(mon, "info");
>  }
>  
> -void hmp_info_sync_profile(Monitor *mon, const QDict *qdict)
> +void hmp_info_sync_profile(MonitorHMP *hmp, const QDict *qdict)
>  {
>      int64_t max = qdict_get_try_int(qdict, "max", 10);
>      bool mean = qdict_get_try_bool(qdict, "mean", false);
> @@ -288,9 +301,9 @@ void hmp_info_sync_profile(Monitor *mon, const QDict *qdict)
>      qsp_report(max, sort_by, coalesce);
>  }
>  
> -void hmp_info_history(Monitor *mon, const QDict *qdict)
> +void hmp_info_history(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    MonitorHMP *hmp = MONITOR_HMP(mon);
> +    Monitor *mon = MONITOR(hmp);
>      int i;
>      const char *str;
>  
> @@ -308,7 +321,7 @@ void hmp_info_history(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_logfile(Monitor *mon, const QDict *qdict)
> +void hmp_logfile(MonitorHMP *hmp, const QDict *qdict)
>  {
>      Error *err = NULL;
>  
> @@ -317,8 +330,9 @@ void hmp_logfile(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_log(Monitor *mon, const QDict *qdict)
> +void hmp_log(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int mask;
>      const char *items = qdict_get_str(qdict, "items");
>      Error *err = NULL;
> @@ -338,8 +352,9 @@ void hmp_log(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_gdbserver(Monitor *mon, const QDict *qdict)
> +void hmp_gdbserver(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *device = qdict_get_try_str(qdict, "device");
>  
> @@ -357,8 +372,9 @@ void hmp_gdbserver(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_print(Monitor *mon, const QDict *qdict)
> +void hmp_print(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int format = qdict_get_int(qdict, "format");
>      hwaddr val = qdict_get_int(qdict, "val");
>  
> @@ -383,8 +399,9 @@ void hmp_print(Monitor *mon, const QDict *qdict)
>      monitor_printf(mon, "\n");
>  }
>  
> -void hmp_sum(Monitor *mon, const QDict *qdict)
> +void hmp_sum(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      uint32_t addr;
>      uint16_t sum;
>      uint32_t start = qdict_get_int(qdict, "start");
> @@ -401,8 +418,9 @@ void hmp_sum(Monitor *mon, const QDict *qdict)
>      monitor_printf(mon, "%05d\n", sum);
>  }
>  
> -void hmp_ioport_read(Monitor *mon, const QDict *qdict)
> +void hmp_ioport_read(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int size = qdict_get_int(qdict, "size");
>      int addr = qdict_get_int(qdict, "addr");
>      int has_index = qdict_haskey(qdict, "index");
> @@ -435,7 +453,7 @@ void hmp_ioport_read(Monitor *mon, const QDict *qdict)
>                     suffix, addr, size * 2, val);
>  }
>  
> -void hmp_ioport_write(Monitor *mon, const QDict *qdict)
> +void hmp_ioport_write(MonitorHMP *hmp, const QDict *qdict)
>  {
>      int size = qdict_get_int(qdict, "size");
>      int addr = qdict_get_int(qdict, "addr");
> @@ -457,8 +475,9 @@ void hmp_ioport_write(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_boot_set(Monitor *mon, const QDict *qdict)
> +void hmp_boot_set(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *local_err = NULL;
>      const char *bootdevice = qdict_get_str(qdict, "bootdevice");
>  
> @@ -470,7 +489,7 @@ void hmp_boot_set(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_info_mtree(Monitor *mon, const QDict *qdict)
> +void hmp_info_mtree(MonitorHMP *hmp, const QDict *qdict)
>  {
>      bool flatview = qdict_get_try_bool(qdict, "flatview", false);
>      bool dispatch_tree = qdict_get_try_bool(qdict, "dispatch_tree", false);
> @@ -481,8 +500,9 @@ void hmp_info_mtree(Monitor *mon, const QDict *qdict)
>  }
>  
>  #if defined(CONFIG_FDT)
> -void hmp_dumpdtb(Monitor *mon, const QDict *qdict)
> +void hmp_dumpdtb(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *filename = qdict_get_str(qdict, "filename");
>      Error *local_err = NULL;
>  
> @@ -558,8 +578,9 @@ int monitor_get_cpu_index(Monitor *mon)
>      return cs ? cs->cpu_index : UNASSIGNED_CPU_INDEX;
>  }
>  
> -void hmp_info_registers(Monitor *mon, const QDict *qdict)
> +void hmp_info_registers(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      bool all_cpus = qdict_get_try_bool(qdict, "cpustate_all", false);
>      int vcpu = qdict_get_try_int(qdict, "vcpu", -1);
>      CPUState *cs;
> @@ -694,8 +715,9 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
>      }
>  }
>  
> -void hmp_memory_dump(Monitor *mon, const QDict *qdict)
> +void hmp_memory_dump(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int count = qdict_get_int(qdict, "count");
>      int format = qdict_get_int(qdict, "format");
>      int size = qdict_get_int(qdict, "size");
> @@ -704,8 +726,9 @@ void hmp_memory_dump(Monitor *mon, const QDict *qdict)
>      memory_dump(mon, count, format, size, addr, false);
>  }
>  
> -void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
> +void hmp_physical_memory_dump(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int count = qdict_get_int(qdict, "count");
>      int format = qdict_get_int(qdict, "format");
>      int size = qdict_get_int(qdict, "size");
> @@ -714,8 +737,9 @@ void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
>      memory_dump(mon, count, format, size, addr, true);
>  }
>  
> -void hmp_gpa2hva(Monitor *mon, const QDict *qdict)
> +void hmp_gpa2hva(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      hwaddr addr = qdict_get_int(qdict, "addr");
>      Error *local_err = NULL;
>      MemoryRegion *mr = NULL;
> @@ -734,8 +758,9 @@ void hmp_gpa2hva(Monitor *mon, const QDict *qdict)
>      memory_region_unref(mr);
>  }
>  
> -void hmp_gva2gpa(Monitor *mon, const QDict *qdict)
> +void hmp_gva2gpa(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      vaddr addr = qdict_get_int(qdict, "addr");
>      CPUState *cs = mon_get_cpu(mon);
>      TranslateForDebugResult tres;
> @@ -787,8 +812,9 @@ out:
>      return ret;
>  }
>  
> -void hmp_gpa2hpa(Monitor *mon, const QDict *qdict)
> +void hmp_gpa2hpa(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      hwaddr addr = qdict_get_int(qdict, "addr");
>      Error *local_err = NULL;
>      MemoryRegion *mr = NULL;
> diff --git a/monitor/hmp.c b/monitor/hmp.c
> index b4d05d47c4bf..6e6334b64685 100644
> --- a/monitor/hmp.c
> +++ b/monitor/hmp.c
> @@ -1228,12 +1228,12 @@ static void hmp_info_human_readable_text(Monitor *mon,
>      monitor_puts(mon, info->human_readable_text);
>  }
>  
> -static void handle_hmp_command_exec(Monitor *mon,
> +static void handle_hmp_command_exec(MonitorHMP *mon,
>                                      const HMPCommand *cmd,
>                                      QDict *qdict)
>  {
>      if (cmd->cmd_info_hrt) {
> -        hmp_info_human_readable_text(mon,
> +        hmp_info_human_readable_text(MONITOR(mon),
>                                       cmd->cmd_info_hrt);
>      } else {
>          cmd->cmd(mon, qdict);
> @@ -1241,7 +1241,7 @@ static void handle_hmp_command_exec(Monitor *mon,
>  }
>  
>  typedef struct HandleHmpCommandCo {
> -    Monitor *mon;
> +    MonitorHMP *mon;
>      const HMPCommand *cmd;
>      QDict *qdict;
>      bool done;
> @@ -1289,19 +1289,18 @@ void handle_hmp_command(MonitorHMP *hmp, const char *cmdline)
>  
>      if (!cmd->coroutine) {
>          /* old_mon is non-NULL when called from qmp_human_monitor_command() */
> -        Monitor *old_mon = monitor_set_cur(qemu_coroutine_self(),
> -                                           &hmp->parent_obj);
> -        handle_hmp_command_exec(&hmp->parent_obj, cmd, qdict);
> +        Monitor *old_mon = monitor_set_cur(qemu_coroutine_self(), MONITOR(hmp));
> +        handle_hmp_command_exec(hmp, cmd, qdict);
>          monitor_set_cur(qemu_coroutine_self(), old_mon);
>      } else {
>          HandleHmpCommandCo data = {
> -            .mon = &hmp->parent_obj,
> +            .mon = hmp,
>              .cmd = cmd,
>              .qdict = qdict,
>              .done = false,
>          };
>          Coroutine *co = qemu_coroutine_create(handle_hmp_command_co, &data);
> -        monitor_set_cur(co, &hmp->parent_obj);
> +        monitor_set_cur(co, MONITOR(hmp));
>          aio_co_enter(qemu_get_aio_context(), co);
>          AIO_WAIT_WHILE_UNLOCKED(NULL, !data.done);
>      }
> @@ -1689,7 +1688,7 @@ int hmp_compare_cmd(const char *name, const char *list)
>  }
>  
>  void monitor_register_hmp(const char *name, bool info,
> -                          void (*cmd)(Monitor *mon, const QDict *qdict))
> +                          void (*cmd)(MonitorHMP *mon, const QDict *qdict))
>  {
>      HMPCommand *table = hmp_cmds_for_target(info);
>  
> diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
> index ee9ba0c8231e..a0fa37c887ed 100644
> --- a/monitor/monitor-internal.h
> +++ b/monitor/monitor-internal.h
> @@ -77,7 +77,7 @@ typedef struct HMPCommand {
>      const char *params;
>      const char *help;
>      const char *flags; /* p=preconfig */
> -    void (*cmd)(Monitor *mon, const QDict *qdict);
> +    void (*cmd)(MonitorHMP *mon, const QDict *qdict);
>      /*
>       * If implementing a command that takes no arguments and simply
>       * prints formatted data, then leave @cmd NULL, and then set
> diff --git a/net/net-hmp-cmds.c b/net/net-hmp-cmds.c
> index 52ac8da770d9..702103b6a920 100644
> --- a/net/net-hmp-cmds.c
> +++ b/net/net-hmp-cmds.c
> @@ -45,8 +45,9 @@ static void hmp_print_client_info(Monitor *mon, NetworkClientInfo *ci)
>      }
>  }
>  
> -void hmp_info_network(Monitor *mon, const QDict *qdict)
> +void hmp_info_network(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      g_autoptr(NetworkInfo) info = qmp_x_query_network(&err);
>      NetHubInfoList *h;
> @@ -83,8 +84,9 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_set_link(Monitor *mon, const QDict *qdict)
> +void hmp_set_link(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *name = qdict_get_str(qdict, "name");
>      bool up = qdict_get_bool(qdict, "up");
>      Error *err = NULL;
> @@ -94,7 +96,7 @@ void hmp_set_link(Monitor *mon, const QDict *qdict)
>  }
>  
>  
> -void hmp_announce_self(Monitor *mon, const QDict *qdict)
> +void hmp_announce_self(MonitorHMP *hmp, const QDict *qdict)
>  {
>      const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
>      const char *id = qdict_get_try_str(qdict, "id");
> @@ -109,8 +111,9 @@ void hmp_announce_self(Monitor *mon, const QDict *qdict)
>      qapi_free_AnnounceParameters(params);
>  }
>  
> -void hmp_netdev_add(Monitor *mon, const QDict *qdict)
> +void hmp_netdev_add(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      QemuOpts *opts;
>      const char *type = qdict_get_try_str(qdict, "type");
> @@ -133,8 +136,9 @@ out:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_netdev_del(Monitor *mon, const QDict *qdict)
> +void hmp_netdev_del(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *id = qdict_get_str(qdict, "id");
>      Error *err = NULL;
>  
> diff --git a/net/slirp.c b/net/slirp.c
> index 9bf09a2c8bc9..d5c190b48b76 100644
> --- a/net/slirp.c
> +++ b/net/slirp.c
> @@ -733,8 +733,9 @@ static SlirpState *slirp_lookup(Monitor *mon, const char *id)
>      }
>  }
>  
> -void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
> +void hmp_hostfwd_remove(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      /* TODO: support removing unix fwd */
>      struct sockaddr_in host_addr = {
>          .sin_family = AF_INET,
> @@ -957,8 +958,9 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
>      return -1;
>  }
>  
> -void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
> +void hmp_hostfwd_add(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *redir_str;
>      SlirpState *s;
>      const char *arg1 = qdict_get_str(qdict, "arg1");
> @@ -1224,8 +1226,9 @@ UsernetInfoList *qmp_x_query_usernet(Error **errp)
>      return head;
>  }
>  
> -void hmp_info_usernet(Monitor *mon, const QDict *qdict)
> +void hmp_info_usernet(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      g_autoptr(UsernetInfoList) list = NULL;
>      UsernetInfoList *entry;
>  
> diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c
> index 47110ca58c0d..16847d1ce261 100644
> --- a/qom/qom-hmp-cmds.c
> +++ b/qom/qom-hmp-cmds.c
> @@ -18,8 +18,9 @@
>  #include "qom/object.h"
>  #include "qom/object_interfaces.h"
>  
> -void hmp_qom_list(Monitor *mon, const QDict *qdict)
> +void hmp_qom_list(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *path = qdict_get_try_str(qdict, "path");
>      ObjectPropertyInfoList *list;
>      Error *err = NULL;
> @@ -44,8 +45,9 @@ void hmp_qom_list(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_qom_set(Monitor *mon, const QDict *qdict)
> +void hmp_qom_set(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const bool json = qdict_get_try_bool(qdict, "json", false);
>      const char *path = qdict_get_str(qdict, "path");
>      const char *property = qdict_get_str(qdict, "property");
> @@ -72,8 +74,9 @@ void hmp_qom_set(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_qom_get(Monitor *mon, const QDict *qdict)
> +void hmp_qom_get(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *path = qdict_get_str(qdict, "path");
>      const char *property = qdict_get_str(qdict, "property");
>      Error *err = NULL;
> @@ -132,8 +135,9 @@ static void print_qom_composition(Monitor *mon, Object *obj, int indent)
>      g_array_free(children, TRUE);
>  }
>  
> -void hmp_info_qom_tree(Monitor *mon, const QDict *dict)
> +void hmp_info_qom_tree(MonitorHMP *hmp, const QDict *dict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *path = qdict_get_try_str(dict, "path");
>      Object *obj;
>      bool ambiguous = false;
> @@ -154,8 +158,9 @@ void hmp_info_qom_tree(Monitor *mon, const QDict *dict)
>      print_qom_composition(mon, obj, 0);
>  }
>  
> -void hmp_object_add(Monitor *mon, const QDict *qdict)
> +void hmp_object_add(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *options = qdict_get_str(qdict, "object");
>      Error *err = NULL;
>  
> @@ -163,8 +168,9 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_object_del(Monitor *mon, const QDict *qdict)
> +void hmp_object_del(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *id = qdict_get_str(qdict, "id");
>      Error *err = NULL;
>  
> diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
> index 7b904a141654..ef69d23ff507 100644
> --- a/replay/replay-debugging.c
> +++ b/replay/replay-debugging.c
> @@ -31,8 +31,9 @@ bool replay_running_debug(void)
>      return replay_is_debugging;
>  }
>  
> -void hmp_info_replay(Monitor *mon, const QDict *qdict)
> +void hmp_info_replay(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      if (replay_mode == REPLAY_MODE_NONE) {
>          monitor_printf(mon, "Record/replay is not active\n");
>      } else {
> @@ -103,7 +104,7 @@ void qmp_replay_break(int64_t icount, Error **errp)
>      }
>  }
>  
> -void hmp_replay_break(Monitor *mon, const QDict *qdict)
> +void hmp_replay_break(MonitorHMP *hmp, const QDict *qdict)
>  {
>      int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
>      Error *err = NULL;
> @@ -124,7 +125,7 @@ void qmp_replay_delete_break(Error **errp)
>      }
>  }
>  
> -void hmp_replay_delete_break(Monitor *mon, const QDict *qdict)
> +void hmp_replay_delete_break(MonitorHMP *hmp, const QDict *qdict)
>  {
>      Error *err = NULL;
>  
> @@ -209,7 +210,7 @@ void qmp_replay_seek(int64_t icount, Error **errp)
>      replay_seek(icount, replay_stop_vm, errp);
>  }
>  
> -void hmp_replay_seek(Monitor *mon, const QDict *qdict)
> +void hmp_replay_seek(MonitorHMP *hmp, const QDict *qdict)
>  {
>      int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
>      Error *err = NULL;
> diff --git a/replay/stubs-system.c b/replay/stubs-system.c
> index f8e17dcf1ce9..15e7411591ab 100644
> --- a/replay/stubs-system.c
> +++ b/replay/stubs-system.c
> @@ -63,19 +63,19 @@ void replay_vmstate_init(void)
>  #include "qapi/error.h"
>  #include "qemu/error-report.h"
>  
> -void hmp_info_replay(Monitor *mon, const QDict *qdict)
> +void hmp_info_replay(MonitorHMP *hmp, const QDict *qdict)
>  {
>      error_report("replay support not available");
>  }
> -void hmp_replay_break(Monitor *mon, const QDict *qdict)
> +void hmp_replay_break(MonitorHMP *hmp, const QDict *qdict)
>  {
>      error_report("replay support not available");
>  }
> -void hmp_replay_delete_break(Monitor *mon, const QDict *qdict)
> +void hmp_replay_delete_break(MonitorHMP *hmp, const QDict *qdict)
>  {
>      error_report("replay support not available");
>  }
> -void hmp_replay_seek(Monitor *mon, const QDict *qdict)
> +void hmp_replay_seek(MonitorHMP *hmp, const QDict *qdict)
>  {
>      error_report("replay support not available");
>  }
> diff --git a/stats/stats-hmp-cmds.c b/stats/stats-hmp-cmds.c
> index b93b471b1b25..f280ad8c4314 100644
> --- a/stats/stats-hmp-cmds.c
> +++ b/stats/stats-hmp-cmds.c
> @@ -187,8 +187,9 @@ static StatsFilter *stats_filter(StatsTarget target, const char *names,
>      return filter;
>  }
>  
> -void hmp_info_stats(Monitor *mon, const QDict *qdict)
> +void hmp_info_stats(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *target_str = qdict_get_str(qdict, "target");
>      const char *provider_str = qdict_get_try_str(qdict, "provider");
>      const char *names = qdict_get_try_str(qdict, "names");
> diff --git a/stubs/hmp-cmd-info_sev.c b/stubs/hmp-cmd-info_sev.c
> index f3624423a334..6f2b87d1ad10 100644
> --- a/stubs/hmp-cmd-info_sev.c
> +++ b/stubs/hmp-cmd-info_sev.c
> @@ -10,7 +10,8 @@
>  #include "monitor/hmp.h"
>  #include "monitor/monitor.h"
>  
> -void hmp_info_sev(Monitor *mon, const QDict *qdict)
> +void hmp_info_sev(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      monitor_printf(mon, "SEV is not available in this QEMU\n");
>  }
> diff --git a/system/dirtylimit-hmp-cmds.c b/system/dirtylimit-hmp-cmds.c
> index 4928d57cc8e3..4c100783778f 100644
> --- a/system/dirtylimit-hmp-cmds.c
> +++ b/system/dirtylimit-hmp-cmds.c
> @@ -15,8 +15,9 @@
>  #include "monitor/monitor.h"
>  #include "system/dirtylimit.h"
>  
> -void hmp_cancel_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
> +void hmp_cancel_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int64_t cpu_index = qdict_get_try_int(qdict, "cpu_index", -1);
>      Error *err = NULL;
>  
> @@ -30,8 +31,9 @@ void hmp_cancel_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
>                     "dirty limit for virtual CPU]\n");
>  }
>  
> -void hmp_set_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
> +void hmp_set_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int64_t dirty_rate = qdict_get_int(qdict, "dirty_rate");
>      int64_t cpu_index = qdict_get_try_int(qdict, "cpu_index", -1);
>      Error *err = NULL;
> @@ -47,8 +49,9 @@ out:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
> +void hmp_info_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      DirtyLimitInfoList *info;
>      g_autoptr(DirtyLimitInfoList) head = NULL;
>      Error *err = NULL;
> diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
> index 00fed791cce1..e27b9724867a 100644
> --- a/system/qdev-monitor.c
> +++ b/system/qdev-monitor.c
> @@ -851,8 +851,9 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent, bool details)
>  }
>  #undef qdev_printf
>  
> -void hmp_info_qtree(Monitor *mon, const QDict *qdict)
> +void hmp_info_qtree(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      bool details = !qdict_get_try_bool(qdict, "brief", false);
>  
>      if (sysbus_get_default()) {
> @@ -860,7 +861,7 @@ void hmp_info_qtree(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_info_qdm(Monitor *mon, const QDict *qdict)
> +void hmp_info_qdm(MonitorHMP *hmp, const QDict *qdict)
>  {
>      qdev_print_devinfos(true);
>  }
> @@ -1001,8 +1002,9 @@ void qmp_device_sync_config(const char *id, Error **errp)
>      qdev_sync_config(dev, errp);
>  }
>  
> -void hmp_device_add(Monitor *mon, const QDict *qdict)
> +void hmp_device_add(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      QemuOpts *opts;
>      DeviceState *dev;
> @@ -1035,8 +1037,9 @@ out:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_device_del(Monitor *mon, const QDict *qdict)
> +void hmp_device_del(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *id = qdict_get_str(qdict, "id");
>      Error *err = NULL;
>  
> diff --git a/system/runstate-hmp-cmds.c b/system/runstate-hmp-cmds.c
> index 02d1d42bf392..834b95835339 100644
> --- a/system/runstate-hmp-cmds.c
> +++ b/system/runstate-hmp-cmds.c
> @@ -23,8 +23,9 @@
>  #include "qobject/qdict.h"
>  #include "qemu/accel.h"
>  
> -void hmp_info_status(Monitor *mon, const QDict *qdict)
> +void hmp_info_status(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      StatusInfo *info;
>  
>      info = qmp_query_status(NULL);
> @@ -41,8 +42,9 @@ void hmp_info_status(Monitor *mon, const QDict *qdict)
>      qapi_free_StatusInfo(info);
>  }
>  
> -void hmp_one_insn_per_tb(Monitor *mon, const QDict *qdict)
> +void hmp_one_insn_per_tb(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *option = qdict_get_try_str(qdict, "option");
>      AccelState *accel = current_accel();
>      bool newval;
> @@ -66,8 +68,9 @@ void hmp_one_insn_per_tb(Monitor *mon, const QDict *qdict)
>                               newval, &error_abort);
>  }
>  
> -void hmp_watchdog_action(Monitor *mon, const QDict *qdict)
> +void hmp_watchdog_action(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      WatchdogAction action;
>      char *qapi_value;
> diff --git a/system/tpm-hmp-cmds.c b/system/tpm-hmp-cmds.c
> index 9ed6ad6c4d46..094c3f16cf50 100644
> --- a/system/tpm-hmp-cmds.c
> +++ b/system/tpm-hmp-cmds.c
> @@ -11,8 +11,9 @@
>  #include "monitor/hmp.h"
>  #include "qapi/error.h"
>  
> -void hmp_info_tpm(Monitor *mon, const QDict *qdict)
> +void hmp_info_tpm(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>  #ifdef CONFIG_TPM
>      TPMInfoList *info_list, *info;
>      Error *err = NULL;
> diff --git a/target/i386/cpu-apic.c b/target/i386/cpu-apic.c
> index 04b7257ad120..2cb3147837d1 100644
> --- a/target/i386/cpu-apic.c
> +++ b/target/i386/cpu-apic.c
> @@ -80,8 +80,9 @@ void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
>       }
>  }
>  
> -void hmp_info_local_apic(Monitor *mon, const QDict *qdict)
> +void hmp_info_local_apic(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      CPUState *cs;
>  
>      if (qdict_haskey(qdict, "apic-id")) {
> diff --git a/target/i386/monitor.c b/target/i386/monitor.c
> index 9ed772e6d7f2..f1d2a327ddad 100644
> --- a/target/i386/monitor.c
> +++ b/target/i386/monitor.c
> @@ -209,8 +209,9 @@ static void tlb_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
>  }
>  #endif /* TARGET_X86_64 */
>  
> -void hmp_info_tlb(Monitor *mon, const QDict *qdict)
> +void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      CPUArchState *env;
>      AddressSpace *as;
>  
> @@ -535,8 +536,9 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env, AddressSpace *as)
>  }
>  #endif /* TARGET_X86_64 */
>  
> -void hmp_info_mem(Monitor *mon, const QDict *qdict)
> +void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      CPUArchState *env;
>      AddressSpace *as;
>  
> @@ -569,8 +571,9 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> -void hmp_mce(Monitor *mon, const QDict *qdict)
> +void hmp_mce(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      X86CPU *cpu;
>      CPUState *cs;
>      int cpu_index = qdict_get_int(qdict, "cpu_index");
> diff --git a/target/i386/sev.c b/target/i386/sev.c
> index d7dcefc8ecf5..4473d02981ff 100644
> --- a/target/i386/sev.c
> +++ b/target/i386/sev.c
> @@ -754,8 +754,9 @@ SevInfo *qmp_query_sev(Error **errp)
>      return info;
>  }
>  
> -void hmp_info_sev(Monitor *mon, const QDict *qdict)
> +void hmp_info_sev(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      SevInfo *info = sev_get_info();
>  
>      if (!info || !info->enabled) {
> diff --git a/target/m68k/monitor.c b/target/m68k/monitor.c
> index 3e0df40a6b8b..0414474f2ffb 100644
> --- a/target/m68k/monitor.c
> +++ b/target/m68k/monitor.c
> @@ -10,8 +10,9 @@
>  #include "monitor/hmp.h"
>  #include "monitor/monitor.h"
>  
> -void hmp_info_tlb(Monitor *mon, const QDict *qdict)
> +void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      CPUArchState *env1 = mon_get_cpu_env(mon);
>  
>      if (!env1) {
> diff --git a/target/ppc/monitor.c b/target/ppc/monitor.c
> index 7c88e0e2bda0..99eda7351877 100644
> --- a/target/ppc/monitor.c
> +++ b/target/ppc/monitor.c
> @@ -11,8 +11,9 @@
>  #include "monitor/hmp.h"
>  #include "cpu.h"
>  
> -void hmp_info_tlb(Monitor *mon, const QDict *qdict)
> +void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      CPUArchState *env1 = mon_get_cpu_env(mon);
>  
>      if (!env1) {
> diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
> index f8042db9cdf3..496d519c978d 100644
> --- a/target/riscv/monitor.c
> +++ b/target/riscv/monitor.c
> @@ -215,8 +215,9 @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
>                last_paddr + last_size - pbase, last_attr);
>  }
>  
> -void hmp_info_mem(Monitor *mon, const QDict *qdict)
> +void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      CPUArchState *env;
>  
>      env = mon_get_cpu_env(mon);
> diff --git a/target/sh4/monitor.c b/target/sh4/monitor.c
> index 50324d3600c4..50da650b2e04 100644
> --- a/target/sh4/monitor.c
> +++ b/target/sh4/monitor.c
> @@ -38,8 +38,9 @@ static void print_tlb(Monitor *mon, int idx, tlb_t *tlb)
>                     tlb->d, tlb->wt);
>  }
>  
> -void hmp_info_tlb(Monitor *mon, const QDict *qdict)
> +void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      CPUArchState *env = mon_get_cpu_env(mon);
>      int i;
>  
> diff --git a/target/sparc/monitor.c b/target/sparc/monitor.c
> index 36f3d8d58e9d..09a15b821a1a 100644
> --- a/target/sparc/monitor.c
> +++ b/target/sparc/monitor.c
> @@ -27,8 +27,9 @@
>  #include "monitor/hmp.h"
>  
>  
> -void hmp_info_tlb(Monitor *mon, const QDict *qdict)
> +void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      CPUArchState *env1 = mon_get_cpu_env(mon);
>  
>      if (!env1) {
> diff --git a/target/xtensa/monitor.c b/target/xtensa/monitor.c
> index 2af84934f83d..a1082c44e11c 100644
> --- a/target/xtensa/monitor.c
> +++ b/target/xtensa/monitor.c
> @@ -26,8 +26,9 @@
>  #include "monitor/monitor.h"
>  #include "monitor/hmp.h"
>  
> -void hmp_info_tlb(Monitor *mon, const QDict *qdict)
> +void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      CPUArchState *env1 = mon_get_cpu_env(mon);
>  
>      if (!env1) {
> diff --git a/trace/trace-hmp-cmds.c b/trace/trace-hmp-cmds.c
> index c8f0133abecf..5a8158f4f4b6 100644
> --- a/trace/trace-hmp-cmds.c
> +++ b/trace/trace-hmp-cmds.c
> @@ -33,7 +33,7 @@
>  #include "trace/simple.h"
>  #endif
>  
> -void hmp_trace_event(Monitor *mon, const QDict *qdict)
> +void hmp_trace_event(MonitorHMP *hmp, const QDict *qdict)
>  {
>      const char *tp_name = qdict_get_str(qdict, "name");
>      bool new_state = qdict_get_bool(qdict, "option");
> @@ -47,8 +47,9 @@ void hmp_trace_event(Monitor *mon, const QDict *qdict)
>  }
>  
>  #ifdef CONFIG_TRACE_SIMPLE
> -void hmp_trace_file(Monitor *mon, const QDict *qdict)
> +void hmp_trace_file(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *op = qdict_get_try_str(qdict, "op");
>      const char *arg = qdict_get_try_str(qdict, "arg");
>  
> @@ -71,8 +72,9 @@ void hmp_trace_file(Monitor *mon, const QDict *qdict)
>  }
>  #endif
>  
> -void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
> +void hmp_info_trace_events(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *name = qdict_get_try_str(qdict, "name");
>      TraceEventInfoList *events;
>      TraceEventInfoList *elem;
> diff --git a/ui/ui-hmp-cmds.c b/ui/ui-hmp-cmds.c
> index 4ef459490ba2..5f3522943c56 100644
> --- a/ui/ui-hmp-cmds.c
> +++ b/ui/ui-hmp-cmds.c
> @@ -29,7 +29,7 @@
>  
>  static int mouse_button_state;
>  
> -void hmp_mouse_move(Monitor *mon, const QDict *qdict)
> +void hmp_mouse_move(MonitorHMP *hmp, const QDict *qdict)
>  {
>      int dx, dy, dz, button;
>      const char *dx_str = qdict_get_str(qdict, "dx_str");
> @@ -53,7 +53,7 @@ void hmp_mouse_move(Monitor *mon, const QDict *qdict)
>      qemu_input_event_sync();
>  }
>  
> -void hmp_mouse_button(Monitor *mon, const QDict *qdict)
> +void hmp_mouse_button(MonitorHMP *hmp, const QDict *qdict)
>  {
>      /* HMP mouse_button bitmask: 1=L, 2=R, 4=M */
>      static uint32_t bmap[INPUT_BUTTON__MAX] = {
> @@ -71,16 +71,18 @@ void hmp_mouse_button(Monitor *mon, const QDict *qdict)
>      mouse_button_state = button_state;
>  }
>  
> -void hmp_mouse_set(Monitor *mon, const QDict *qdict)
> +void hmp_mouse_set(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qemu_mouse_set(qdict_get_int(qdict, "index"), &err);
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_info_mice(Monitor *mon, const QDict *qdict)
> +void hmp_info_mice(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      MouseInfoList *mice_list, *mouse;
>  
>      mice_list = qmp_query_mice(NULL);
> @@ -148,8 +150,9 @@ static void hmp_info_vnc_servers(Monitor *mon, VncServerInfo2List *server)
>      }
>  }
>  
> -void hmp_info_vnc(Monitor *mon, const QDict *qdict)
> +void hmp_info_vnc(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      VncInfo2List *info2l, *info2l_head;
>      Error *err = NULL;
>  
> @@ -189,8 +192,9 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict)
>  #endif
>  
>  #ifdef CONFIG_SPICE
> -void hmp_info_spice(Monitor *mon, const QDict *qdict)
> +void hmp_info_spice(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      SpiceChannelList *chan;
>      SpiceInfo *info;
>      const char *channel_name;
> @@ -260,8 +264,9 @@ out:
>  }
>  #endif
>  
> -void hmp_set_password(Monitor *mon, const QDict *qdict)
> +void hmp_set_password(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *protocol  = qdict_get_str(qdict, "protocol");
>      const char *password  = qdict_get_str(qdict, "password");
>      const char *display = qdict_get_try_str(qdict, "display");
> @@ -295,8 +300,9 @@ out:
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_expire_password(Monitor *mon, const QDict *qdict)
> +void hmp_expire_password(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *protocol  = qdict_get_str(qdict, "protocol");
>      const char *whenstr = qdict_get_str(qdict, "time");
>      const char *display = qdict_get_try_str(qdict, "display");
> @@ -366,8 +372,9 @@ static int index_from_key(const char *key, size_t key_length)
>      return i;
>  }
>  
> -void hmp_sendkey(Monitor *mon, const QDict *qdict)
> +void hmp_sendkey(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *keys = qdict_get_str(qdict, "keys");
>      KeyValue *v = NULL;
>      KeyValueList *head = NULL, **tail = &head;
> @@ -456,8 +463,9 @@ void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
>  
>  #ifdef CONFIG_PIXMAN
>  void coroutine_fn
> -hmp_screendump(Monitor *mon, const QDict *qdict)
> +hmp_screendump(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      const char *filename = qdict_get_str(qdict, "filename");
>      const char *id = qdict_get_try_str(qdict, "device");
>      int64_t head = qdict_get_try_int(qdict, "head", 0);
> @@ -478,8 +486,9 @@ end:
>  }
>  #endif
>  
> -void hmp_client_migrate_info(Monitor *mon, const QDict *qdict)
> +void hmp_client_migrate_info(MonitorHMP *hmp, const QDict *qdict)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *protocol = qdict_get_str(qdict, "protocol");
>      const char *hostname = qdict_get_str(qdict, "hostname");
> 
> -- 
> 2.55.0.543.g5ebe2ebe4ea8
> 
-- 
 -----Open up your eyes, open up your mind, open up your code -------   
/ Dr. David Alan Gilbert    |       Running GNU/Linux       | Happy  \ 
\        dave @ treblig.org |                               | In Hex /
 \ _________________________|_____ http://www.treblig.org   |_______/


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

* Re: [PATCH v3 32/49] monitor: make hmp_handle_error() take MonitorHMP
  2026-08-16 19:12 ` [PATCH v3 32/49] monitor: make hmp_handle_error() " Marc-André Lureau
@ 2026-08-17  0:36   ` Dr. David Alan Gilbert
  0 siblings, 0 replies; 73+ messages in thread
From: Dr. David Alan Gilbert @ 2026-08-17  0:36 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Kevin Wolf, Hanna Reitz, Paolo Bonzini,
	Ani Sinha, David Woodhouse, Paul Durrant, Richard Henderson,
	Michael S. Tsirkin, Mark Cave-Ayland, Jiri Pirko, Jason Wang,
	Gerd Hoffmann, Hyman Huang, Peter Xu, Fabiano Rosas, Zhao Liu,
	qemu-block, qemu-ppc

* Marc-André Lureau (marcandre.lureau@redhat.com) wrote:
> Mostly mechanical, with a few adjustments around it.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Dr. David Alan Gilbert <dave@treblig.org>

> ---
>  block/monitor/block-hmp-cmds.c  | 73 +++++++++++++++--------------------------
>  chardev/char-hmp-cmds.c         | 17 ++++------
>  dump/dump-hmp-cmds.c            |  5 ++-
>  hw/core/machine-hmp-cmds.c      | 26 +++++++--------
>  hw/i386/kvm/xen_evtchn.c        |  4 +--
>  hw/misc/mos6522.c               |  2 +-
>  hw/net/rocker/rocker-hmp-cmds.c |  8 ++---
>  hw/pci/pci-hmp-cmds.c           |  2 +-
>  hw/uefi/ovmf-log.c              |  2 +-
>  hw/virtio/virtio-hmp-cmds.c     | 10 +++---
>  include/monitor/hmp.h           |  2 +-
>  migration/dirtyrate.c           |  2 +-
>  migration/migration-hmp-cmds.c  | 37 ++++++++-------------
>  monitor/hmp-cmds.c              | 23 +++++--------
>  monitor/hmp.c                   | 12 +++----
>  net/net-hmp-cmds.c              | 11 +++----
>  qom/qom-hmp-cmds.c              | 13 +++-----
>  system/dirtylimit-hmp-cmds.c    |  7 ++--
>  system/qdev-monitor.c           |  6 ++--
>  system/runstate-hmp-cmds.c      |  3 +-
>  target/i386/monitor.c           |  3 +-
>  ui/ui-hmp-cmds.c                | 19 ++++-------
>  22 files changed, 112 insertions(+), 175 deletions(-)
> 
> diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
> index 3914b5189d56..a2666e2f1b9b 100644
> --- a/block/monitor/block-hmp-cmds.c
> +++ b/block/monitor/block-hmp-cmds.c
> @@ -57,7 +57,7 @@
>  #include "block/block_int.h"
>  #include "block/block-hmp-cmds.h"
>  
> -static void hmp_drive_add_node(Monitor *mon, const char *optstr)
> +static void hmp_drive_add_node(MonitorHMP *hmp, const char *optstr)
>  {
>      QemuOpts *opts;
>      QDict *qdict;
> @@ -84,7 +84,7 @@ static void hmp_drive_add_node(Monitor *mon, const char *optstr)
>      bdrv_set_monitor_owned(bs);
>  out:
>      qemu_opts_del(opts);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_drive_add(MonitorHMP *hmp, const QDict *qdict)
> @@ -98,7 +98,7 @@ void hmp_drive_add(MonitorHMP *hmp, const QDict *qdict)
>      bool node = qdict_get_try_bool(qdict, "node", false);
>  
>      if (node) {
> -        hmp_drive_add_node(mon, optstr);
> +        hmp_drive_add_node(hmp, optstr);
>          return;
>      }
>  
> @@ -133,12 +133,11 @@ err:
>          monitor_remove_blk(blk);
>          blk_unref(blk);
>      }
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_drive_del(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *id = qdict_get_str(qdict, "id");
>      BlockBackend *blk;
>      BlockDriverState *bs;
> @@ -193,12 +192,11 @@ void hmp_drive_del(MonitorHMP *hmp, const QDict *qdict)
>  
>  unlock:
>      bdrv_graph_rdunlock_main_loop();
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_commit(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      BlockBackend *blk;
>      int ret;
> @@ -232,12 +230,11 @@ void hmp_commit(MonitorHMP *hmp, const QDict *qdict)
>      }
>  
>  end:
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_drive_mirror(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *filename = qdict_get_str(qdict, "target");
>      const char *format = qdict_get_try_str(qdict, "format");
>      bool reuse = qdict_get_try_bool(qdict, "reuse", false);
> @@ -259,12 +256,11 @@ void hmp_drive_mirror(MonitorHMP *hmp, const QDict *qdict)
>      }
>      qmp_drive_mirror(&mirror, &err);
>  end:
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_drive_backup(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *filename = qdict_get_str(qdict, "target");
>      const char *format = qdict_get_try_str(qdict, "format");
> @@ -290,69 +286,63 @@ void hmp_drive_backup(MonitorHMP *hmp, const QDict *qdict)
>  
>      qmp_drive_backup(&backup, &err);
>  end:
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_block_job_set_speed(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *error = NULL;
>      const char *device = qdict_get_str(qdict, "device");
>      int64_t value = qdict_get_int(qdict, "speed");
>  
>      qmp_block_job_set_speed(device, value, &error);
>  
> -    hmp_handle_error(mon, error);
> +    hmp_handle_error(hmp, error);
>  }
>  
>  void hmp_block_job_cancel(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *error = NULL;
>      const char *device = qdict_get_str(qdict, "device");
>      bool force = qdict_get_try_bool(qdict, "force", false);
>  
>      qmp_block_job_cancel(device, true, force, &error);
>  
> -    hmp_handle_error(mon, error);
> +    hmp_handle_error(hmp, error);
>  }
>  
>  void hmp_block_job_pause(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *error = NULL;
>      const char *device = qdict_get_str(qdict, "device");
>  
>      qmp_block_job_pause(device, &error);
>  
> -    hmp_handle_error(mon, error);
> +    hmp_handle_error(hmp, error);
>  }
>  
>  void hmp_block_job_resume(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *error = NULL;
>      const char *device = qdict_get_str(qdict, "device");
>  
>      qmp_block_job_resume(device, &error);
>  
> -    hmp_handle_error(mon, error);
> +    hmp_handle_error(hmp, error);
>  }
>  
>  void hmp_block_job_complete(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *error = NULL;
>      const char *device = qdict_get_str(qdict, "device");
>  
>      qmp_block_job_complete(device, &error);
>  
> -    hmp_handle_error(mon, error);
> +    hmp_handle_error(hmp, error);
>  }
>  
>  void hmp_snapshot_blkdev(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *filename = qdict_get_str(qdict, "snapshot-file");
>      const char *format = qdict_get_try_str(qdict, "format");
> @@ -363,35 +353,32 @@ void hmp_snapshot_blkdev(MonitorHMP *hmp, const QDict *qdict)
>      mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
>      qmp_blockdev_snapshot_sync(device, NULL, filename, NULL, format,
>                                 true, mode, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_snapshot_blkdev_internal(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *name = qdict_get_str(qdict, "name");
>      Error *err = NULL;
>  
>      qmp_blockdev_snapshot_internal_sync(device, name, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_snapshot_delete_blkdev_internal(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *name = qdict_get_str(qdict, "name");
>      const char *id = qdict_get_try_str(qdict, "id");
>      Error *err = NULL;
>  
>      qmp_blockdev_snapshot_delete_internal_sync(device, id, name, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_nbd_server_start(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *uri = qdict_get_str(qdict, "uri");
>      bool writable = qdict_get_try_bool(qdict, "writable", false);
>      bool all = qdict_get_try_bool(qdict, "all", false);
> @@ -449,12 +436,11 @@ void hmp_nbd_server_start(MonitorHMP *hmp, const QDict *qdict)
>      qapi_free_BlockInfoList(block_list);
>  
>  exit:
> -    hmp_handle_error(mon, local_err);
> +    hmp_handle_error(hmp, local_err);
>  }
>  
>  void hmp_nbd_server_add(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *name = qdict_get_try_str(qdict, "name");
>      bool writable = qdict_get_try_bool(qdict, "writable", false);
> @@ -468,44 +454,40 @@ void hmp_nbd_server_add(MonitorHMP *hmp, const QDict *qdict)
>      };
>  
>      qmp_nbd_server_add(&export, &local_err);
> -    hmp_handle_error(mon, local_err);
> +    hmp_handle_error(hmp, local_err);
>  }
>  
>  void hmp_nbd_server_remove(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *name = qdict_get_str(qdict, "name");
>      bool force = qdict_get_try_bool(qdict, "force", false);
>      Error *err = NULL;
>  
>      /* Rely on BLOCK_EXPORT_REMOVE_MODE_SAFE being the default */
>      qmp_nbd_server_remove(name, force, BLOCK_EXPORT_REMOVE_MODE_HARD, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_nbd_server_stop(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_nbd_server_stop(&err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void coroutine_fn hmp_block_resize(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *device = qdict_get_str(qdict, "device");
>      int64_t size = qdict_get_int(qdict, "size");
>      Error *err = NULL;
>  
>      qmp_block_resize(device, NULL, size, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_block_stream(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *error = NULL;
>      const char *device = qdict_get_str(qdict, "device");
>      const char *base = qdict_get_try_str(qdict, "base");
> @@ -516,12 +498,11 @@ void hmp_block_stream(MonitorHMP *hmp, const QDict *qdict)
>                       true, BLOCKDEV_ON_ERROR_REPORT, NULL,
>                       false, false, false, false, &error);
>  
> -    hmp_handle_error(mon, error);
> +    hmp_handle_error(hmp, error);
>  }
>  
>  void hmp_block_set_io_throttle(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      char *device = (char *) qdict_get_str(qdict, "device");
>      BlockIOThrottle throttle = {
> @@ -545,23 +526,21 @@ void hmp_block_set_io_throttle(MonitorHMP *hmp, const QDict *qdict)
>      }
>  
>      qmp_block_set_io_throttle(&throttle, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_eject(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      bool force = qdict_get_try_bool(qdict, "force", false);
>      const char *device = qdict_get_str(qdict, "device");
>      Error *err = NULL;
>  
>      qmp_eject(device, NULL, true, force, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_qemu_io(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      bool qdev = qdict_get_try_bool(qdict, "qdev", false);
>      const char *device = qdict_get_str(qdict, "device");
>      const char *command = qdict_get_str(qdict, "command");
> @@ -570,7 +549,7 @@ void hmp_qemu_io(MonitorHMP *hmp, const QDict *qdict)
>      qmp_x_qemu_io(qdev ? NULL : device,
>                    qdev ? device : NULL,
>                    command, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  static void print_block_info(Monitor *mon, BlockInfo *info,
> @@ -851,7 +830,7 @@ void hmp_info_snapshots(MonitorHMP *hmp, const QDict *qdict)
>  
>      bs = bdrv_all_find_vmstate_bs(NULL, false, NULL, &err);
>      if (!bs) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>  
> diff --git a/chardev/char-hmp-cmds.c b/chardev/char-hmp-cmds.c
> index d4a5a3a255a5..71017fd2d19e 100644
> --- a/chardev/char-hmp-cmds.c
> +++ b/chardev/char-hmp-cmds.c
> @@ -40,14 +40,13 @@ void hmp_info_chardev(MonitorHMP *hmp, const QDict *qdict)
>  
>  void hmp_ringbuf_write(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *chardev = qdict_get_str(qdict, "device");
>      const char *data = qdict_get_str(qdict, "data");
>      Error *err = NULL;
>  
>      qmp_ringbuf_write(chardev, data, false, 0, &err);
>  
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_ringbuf_read(MonitorHMP *hmp, const QDict *qdict)
> @@ -60,7 +59,7 @@ void hmp_ringbuf_read(MonitorHMP *hmp, const QDict *qdict)
>      int i;
>  
>      data = qmp_ringbuf_read(chardev, size, false, 0, &err);
> -    if (hmp_handle_error(mon, err)) {
> +    if (hmp_handle_error(hmp, err)) {
>          return;
>      }
>  
> @@ -82,7 +81,6 @@ void hmp_ringbuf_read(MonitorHMP *hmp, const QDict *qdict)
>  
>  void hmp_chardev_add(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *args = qdict_get_str(qdict, "args");
>      Error *err = NULL;
>      QemuOpts *opts;
> @@ -94,12 +92,11 @@ void hmp_chardev_add(MonitorHMP *hmp, const QDict *qdict)
>          qemu_chr_new_from_opts(opts, NULL, &err);
>          qemu_opts_del(opts);
>      }
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_chardev_change(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *args = qdict_get_str(qdict, "args");
>      const char *id;
>      Error *err = NULL;
> @@ -129,25 +126,23 @@ end:
>      qapi_free_ChardevReturn(ret);
>      qapi_free_ChardevBackend(backend);
>      qemu_opts_del(opts);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_chardev_remove(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *local_err = NULL;
>  
>      qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
> -    hmp_handle_error(mon, local_err);
> +    hmp_handle_error(hmp, local_err);
>  }
>  
>  void hmp_chardev_send_break(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *local_err = NULL;
>  
>      qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err);
> -    hmp_handle_error(mon, local_err);
> +    hmp_handle_error(hmp, local_err);
>  }
>  
>  void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str)
> diff --git a/dump/dump-hmp-cmds.c b/dump/dump-hmp-cmds.c
> index ba78ad026f1e..104ab5d2a53a 100644
> --- a/dump/dump-hmp-cmds.c
> +++ b/dump/dump-hmp-cmds.c
> @@ -14,7 +14,6 @@
>  
>  void hmp_dump_guest_memory(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      bool win_dmp = qdict_get_try_bool(qdict, "windmp", false);
>      bool paging = qdict_get_try_bool(qdict, "paging", false);
> @@ -34,7 +33,7 @@ void hmp_dump_guest_memory(MonitorHMP *hmp, const QDict *qdict)
>  
>      if (zlib + lzo + snappy + win_dmp > 1) {
>          error_setg(&err, "only one of '-z|-l|-s|-w' can be set");
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>  
> @@ -80,7 +79,7 @@ void hmp_dump_guest_memory(MonitorHMP *hmp, const QDict *qdict)
>  
>      qmp_dump_guest_memory(paging, prot, true, detach, has_begin, begin,
>                            has_length, length, true, dump_format, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>      g_free(prot);
>  }
>  
> diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
> index 48fa27f12705..4e2f0c212b0d 100644
> --- a/hw/core/machine-hmp-cmds.c
> +++ b/hw/core/machine-hmp-cmds.c
> @@ -57,7 +57,7 @@ void hmp_hotpluggable_cpus(MonitorHMP *hmp, const QDict *qdict)
>      HotpluggableCPUList *saved = l;
>      CpuInstanceProperties *c;
>  
> -    if (hmp_handle_error(mon, err)) {
> +    if (hmp_handle_error(hmp, err)) {
>          return;
>      }
>  
> @@ -147,7 +147,7 @@ void hmp_info_memdev(MonitorHMP *hmp, const QDict *qdict)
>      monitor_printf(mon, "\n");
>  
>      qapi_free_MemdevList(memdev_list);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_info_kvm(MonitorHMP *hmp, const QDict *qdict)
> @@ -202,7 +202,7 @@ void hmp_info_balloon(MonitorHMP *hmp, const QDict *qdict)
>      Error *err = NULL;
>  
>      info = qmp_query_balloon(&err);
> -    if (hmp_handle_error(mon, err)) {
> +    if (hmp_handle_error(hmp, err)) {
>          return;
>      }
>  
> @@ -236,47 +236,43 @@ void hmp_memsave(MonitorHMP *hmp, const QDict *qdict)
>      }
>  
>      qmp_memsave(addr, size, filename, true, cpu_index, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_pmemsave(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      uint32_t size = qdict_get_int(qdict, "size");
>      const char *filename = qdict_get_str(qdict, "filename");
>      uint64_t addr = qdict_get_int(qdict, "val");
>      Error *err = NULL;
>  
>      qmp_pmemsave(addr, size, filename, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_system_wakeup(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_system_wakeup(&err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_nmi(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_inject_nmi(&err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_balloon(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      int64_t value = qdict_get_int(qdict, "value");
>      Error *err = NULL;
>  
>      qmp_balloon(value, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_info_memory_devices(MonitorHMP *hmp, const QDict *qdict)
> @@ -380,7 +376,7 @@ void hmp_info_memory_devices(MonitorHMP *hmp, const QDict *qdict)
>      }
>  
>      qapi_free_MemoryDeviceInfoList(info_list);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_info_vm_generation_id(MonitorHMP *hmp, const QDict *qdict)
> @@ -391,7 +387,7 @@ void hmp_info_vm_generation_id(MonitorHMP *hmp, const QDict *qdict)
>      if (info) {
>          monitor_printf(mon, "%s\n", info->guid);
>      }
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>      qapi_free_GuidInfo(info);
>  }
>  
> @@ -411,5 +407,5 @@ void hmp_info_memory_size_summary(MonitorHMP *hmp, const QDict *qdict)
>  
>          qapi_free_MemoryInfo(info);
>      }
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
> diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c
> index 845838c372d5..00dff6ee8760 100644
> --- a/hw/i386/kvm/xen_evtchn.c
> +++ b/hw/i386/kvm/xen_evtchn.c
> @@ -2352,7 +2352,7 @@ void hmp_xen_event_list(MonitorHMP *hmp, const QDict *qdict)
>  
>      info_list = qmp_xen_event_list(&err);
>      if (err) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>  
> @@ -2388,7 +2388,7 @@ void hmp_xen_event_inject(MonitorHMP *hmp, const QDict *qdict)
>  
>      qmp_xen_event_inject(port, &err);
>      if (err) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>      } else {
>          monitor_printf(mon, "Delivered port %d\n", port);
>      }
> diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
> index 15a6a1a75745..1c20c7582c34 100644
> --- a/hw/misc/mos6522.c
> +++ b/hw/misc/mos6522.c
> @@ -592,7 +592,7 @@ void hmp_info_via(MonitorHMP *hmp, const QDict *qdict)
>      Error *err = NULL;
>      g_autoptr(HumanReadableText) info = qmp_x_query_via(&err);
>  
> -    if (hmp_handle_error(mon, err)) {
> +    if (hmp_handle_error(hmp, err)) {
>          return;
>      }
>      monitor_puts(mon, info->human_readable_text);
> diff --git a/hw/net/rocker/rocker-hmp-cmds.c b/hw/net/rocker/rocker-hmp-cmds.c
> index 856aaef5e210..6405ce26dd65 100644
> --- a/hw/net/rocker/rocker-hmp-cmds.c
> +++ b/hw/net/rocker/rocker-hmp-cmds.c
> @@ -28,7 +28,7 @@ void hmp_rocker(MonitorHMP *hmp, const QDict *qdict)
>      Error *err = NULL;
>  
>      rocker = qmp_query_rocker(name, &err);
> -    if (hmp_handle_error(mon, err)) {
> +    if (hmp_handle_error(hmp, err)) {
>          return;
>      }
>  
> @@ -47,7 +47,7 @@ void hmp_rocker_ports(MonitorHMP *hmp, const QDict *qdict)
>      Error *err = NULL;
>  
>      list = qmp_query_rocker_ports(name, &err);
> -    if (hmp_handle_error(mon, err)) {
> +    if (hmp_handle_error(hmp, err)) {
>          return;
>      }
>  
> @@ -76,7 +76,7 @@ void hmp_rocker_of_dpa_flows(MonitorHMP *hmp, const QDict *qdict)
>      Error *err = NULL;
>  
>      list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &err);
> -    if (hmp_handle_error(mon, err)) {
> +    if (hmp_handle_error(hmp, err)) {
>          return;
>      }
>  
> @@ -226,7 +226,7 @@ void hmp_rocker_of_dpa_groups(MonitorHMP *hmp, const QDict *qdict)
>      Error *err = NULL;
>  
>      list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &err);
> -    if (hmp_handle_error(mon, err)) {
> +    if (hmp_handle_error(hmp, err)) {
>          return;
>      }
>  
> diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c
> index be24aecc8ac8..51d95d76620e 100644
> --- a/hw/pci/pci-hmp-cmds.c
> +++ b/hw/pci/pci-hmp-cmds.c
> @@ -247,5 +247,5 @@ void hmp_pcie_aer_inject_error(MonitorHMP *hmp, const QDict *qdict)
>                     PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
>  
>  out:
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
> diff --git a/hw/uefi/ovmf-log.c b/hw/uefi/ovmf-log.c
> index c97622b2aad6..0d59a74ad60e 100644
> --- a/hw/uefi/ovmf-log.c
> +++ b/hw/uefi/ovmf-log.c
> @@ -269,7 +269,7 @@ void hmp_info_firmware_log(MonitorHMP *hmp, const QDict *qdict)
>      maxsize = qdict_get_try_int(qdict, "max-size", -1);
>      log = qmp_query_firmware_log(maxsize != -1, (uint64_t)maxsize, &err);
>      if (err)  {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>  
> diff --git a/hw/virtio/virtio-hmp-cmds.c b/hw/virtio/virtio-hmp-cmds.c
> index 49f3367785ba..fb36c8b9274c 100644
> --- a/hw/virtio/virtio-hmp-cmds.c
> +++ b/hw/virtio/virtio-hmp-cmds.c
> @@ -88,7 +88,7 @@ void hmp_virtio_query(MonitorHMP *hmp, const QDict *qdict)
>      VirtioInfoList *node;
>  
>      if (err != NULL) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>  
> @@ -114,7 +114,7 @@ void hmp_virtio_status(MonitorHMP *hmp, const QDict *qdict)
>      VirtioStatus *s = qmp_x_query_virtio_status(path, &err);
>  
>      if (err != NULL) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>  
> @@ -195,7 +195,7 @@ void hmp_vhost_queue_status(MonitorHMP *hmp, const QDict *qdict)
>          qmp_x_query_virtio_vhost_queue_status(path, queue, &err);
>  
>      if (err != NULL) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>  
> @@ -228,7 +228,7 @@ void hmp_virtio_queue_status(MonitorHMP *hmp, const QDict *qdict)
>      VirtQueueStatus *s = qmp_x_query_virtio_queue_status(path, queue, &err);
>  
>      if (err != NULL) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>  
> @@ -278,7 +278,7 @@ void hmp_virtio_queue_element(MonitorHMP *hmp, const QDict *qdict)
>      e = qmp_x_query_virtio_queue_element(path, queue, index != -1,
>                                           index, &err);
>      if (err != NULL) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>  
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index 7a270ad3f25c..827a56144824 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -54,7 +54,7 @@ void monitor_register_hmp_info_hrt(const char *name,
>  CPUArchState *mon_get_cpu_env(Monitor *mon);
>  CPUState *mon_get_cpu(Monitor *mon);
>  
> -bool hmp_handle_error(Monitor *mon, Error *err);
> +bool hmp_handle_error(MonitorHMP *hmp, Error *err);
>  void hmp_help_cmd(Monitor *mon, const char *name);
>  strList *hmp_split_at_comma(const char *str);
>  
> diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
> index 567abab321cc..3c0931796ce2 100644
> --- a/migration/dirtyrate.c
> +++ b/migration/dirtyrate.c
> @@ -926,7 +926,7 @@ void hmp_calc_dirty_rate(MonitorHMP *hmp, const QDict *qdict)
>                          true, mode,
>                          &err);
>      if (err) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>  
> diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c
> index 8d2e8735277e..73a974259478 100644
> --- a/migration/migration-hmp-cmds.c
> +++ b/migration/migration-hmp-cmds.c
> @@ -478,7 +478,6 @@ void hmp_info_migrate_parameters(MonitorHMP *hmp, const QDict *qdict)
>  
>  void hmp_loadvm(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      RunState saved_state = runstate_get();
>  
>      const char *name = qdict_get_str(qdict, "name");
> @@ -490,27 +489,25 @@ void hmp_loadvm(MonitorHMP *hmp, const QDict *qdict)
>          load_snapshot_resume(saved_state);
>      }
>  
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_savevm(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      save_snapshot(qdict_get_try_str(qdict, "name"),
>                    true, NULL, false, NULL, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_delvm(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *name = qdict_get_str(qdict, "name");
>  
>      delete_snapshot(name, false, NULL, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_migrate_cancel(MonitorHMP *hmp, const QDict *qdict)
> @@ -520,7 +517,6 @@ void hmp_migrate_cancel(MonitorHMP *hmp, const QDict *qdict)
>  
>  void hmp_migrate_continue(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *state = qdict_get_str(qdict, "state");
>      int val = qapi_enum_parse(&MigrationStatus_lookup, state, -1, &err);
> @@ -529,12 +525,11 @@ void hmp_migrate_continue(MonitorHMP *hmp, const QDict *qdict)
>          qmp_migrate_continue(val, &err);
>      }
>  
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_migrate_incoming(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *uri = qdict_get_str(qdict, "uri");
>      MigrationChannelList *caps = NULL;
> @@ -549,34 +544,31 @@ void hmp_migrate_incoming(MonitorHMP *hmp, const QDict *qdict)
>      qapi_free_MigrationChannelList(caps);
>  
>  end:
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_migrate_recover(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *uri = qdict_get_str(qdict, "uri");
>  
>      qmp_migrate_recover(uri, &err);
>  
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_migrate_pause(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_migrate_pause(&err);
>  
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  
>  void hmp_migrate_set_capability(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *cap = qdict_get_str(qdict, "capability");
>      bool state = qdict_get_bool(qdict, "state");
>      Error *err = NULL;
> @@ -597,12 +589,11 @@ void hmp_migrate_set_capability(MonitorHMP *hmp, const QDict *qdict)
>      qapi_free_MigrationCapabilityStatusList(caps);
>  
>  end:
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_migrate_set_parameter(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *param = qdict_get_str(qdict, "parameter");
>      const char *valuestr = qdict_get_str(qdict, "value");
>      Visitor *v = string_input_visitor_new(valuestr);
> @@ -799,25 +790,23 @@ void hmp_migrate_set_parameter(MonitorHMP *hmp, const QDict *qdict)
>   cleanup:
>      qapi_free_MigrationParameters(p);
>      visit_free(v);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_migrate_start_postcopy(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      qmp_migrate_start_postcopy(&err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  #ifdef CONFIG_REPLICATION
>  void hmp_x_colo_lost_heartbeat(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_x_colo_lost_heartbeat(&err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  #endif
>  
> @@ -860,7 +849,7 @@ void hmp_migrate(MonitorHMP *hmp, const QDict *qdict)
>      g_autoptr(MigrationChannel) channel_cpr = NULL;
>  
>      if (!migrate_uri_parse(uri, &channel, &err)) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>      QAPI_LIST_PREPEND(caps, g_steal_pointer(&channel));
> @@ -882,7 +871,7 @@ void hmp_migrate(MonitorHMP *hmp, const QDict *qdict)
>      }
>  
>      qmp_migrate(NULL, true, caps, true, resume, &err);
> -    if (hmp_handle_error(mon, err)) {
> +    if (hmp_handle_error(hmp, err)) {
>          return;
>      }
>  
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index afe4817b4056..d1e7e4de6585 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -75,7 +75,7 @@ static void __attribute__((__constructor__)) sortcmdlist(void)
>            compare_mon_cmd);
>  }
>  
> -bool hmp_handle_error(Monitor *mon, Error *err)
> +bool hmp_handle_error(MonitorHMP *hmp, Error *err)
>  {
>      if (err) {
>          error_reportf_err(err, "Error: ");
> @@ -165,17 +165,16 @@ void hmp_sync_profile(MonitorHMP *hmp, const QDict *qdict)
>  
>          error_setg(&err, "invalid parameter '%s',"
>                     " expecting 'on', 'off', or 'reset'", op);
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>      }
>  }
>  
>  void hmp_exit_preconfig(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_x_exit_preconfig(&err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_cpu(MonitorHMP *hmp, const QDict *qdict)
> @@ -193,11 +192,10 @@ void hmp_cpu(MonitorHMP *hmp, const QDict *qdict)
>  
>  void hmp_cont(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qmp_cont(&err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_change(MonitorHMP *hmp, const QDict *qdict)
> @@ -219,29 +217,27 @@ void hmp_change(MonitorHMP *hmp, const QDict *qdict)
>          hmp_change_medium(mon, device, target, arg, read_only, force, &err);
>      }
>  
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  #ifdef CONFIG_POSIX
>  void hmp_getfd(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *fdname = qdict_get_str(qdict, "fdname");
>      Error *err = NULL;
>  
>      qmp_getfd(fdname, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  #endif
>  
>  void hmp_closefd(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *fdname = qdict_get_str(qdict, "fdname");
>      Error *err = NULL;
>  
>      qmp_closefd(fdname, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_info_iothreads(MonitorHMP *hmp, const QDict *qdict)
> @@ -502,17 +498,16 @@ void hmp_info_mtree(MonitorHMP *hmp, const QDict *qdict)
>  #if defined(CONFIG_FDT)
>  void hmp_dumpdtb(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *filename = qdict_get_str(qdict, "filename");
>      Error *local_err = NULL;
>  
>      qmp_dumpdtb(filename, &local_err);
>  
> -    if (hmp_handle_error(mon, local_err)) {
> +    if (hmp_handle_error(hmp, local_err)) {
>          return;
>      }
>  
> -    monitor_printf(mon, "DTB dumped to '%s'\n", filename);
> +    monitor_printf(MONITOR(hmp), "DTB dumped to '%s'\n", filename);
>  }
>  #endif
>  
> diff --git a/monitor/hmp.c b/monitor/hmp.c
> index 6e6334b64685..57c4127641ac 100644
> --- a/monitor/hmp.c
> +++ b/monitor/hmp.c
> @@ -1215,28 +1215,28 @@ fail:
>      return NULL;
>  }
>  
> -static void hmp_info_human_readable_text(Monitor *mon,
> +static void hmp_info_human_readable_text(MonitorHMP *hmp,
>                                           HumanReadableText *(*handler)(Error **))
>  {
>      Error *err = NULL;
>      g_autoptr(HumanReadableText) info = handler(&err);
>  
> -    if (hmp_handle_error(mon, err)) {
> +    if (hmp_handle_error(hmp, err)) {
>          return;
>      }
>  
> -    monitor_puts(mon, info->human_readable_text);
> +    monitor_puts(MONITOR(hmp), info->human_readable_text);
>  }
>  
> -static void handle_hmp_command_exec(MonitorHMP *mon,
> +static void handle_hmp_command_exec(MonitorHMP *hmp,
>                                      const HMPCommand *cmd,
>                                      QDict *qdict)
>  {
>      if (cmd->cmd_info_hrt) {
> -        hmp_info_human_readable_text(MONITOR(mon),
> +        hmp_info_human_readable_text(hmp,
>                                       cmd->cmd_info_hrt);
>      } else {
> -        cmd->cmd(mon, qdict);
> +        cmd->cmd(hmp, qdict);
>      }
>  }
>  
> diff --git a/net/net-hmp-cmds.c b/net/net-hmp-cmds.c
> index 702103b6a920..5b1c678f5d89 100644
> --- a/net/net-hmp-cmds.c
> +++ b/net/net-hmp-cmds.c
> @@ -53,7 +53,7 @@ void hmp_info_network(MonitorHMP *hmp, const QDict *qdict)
>      NetHubInfoList *h;
>      NetworkClientInfoList *entry;
>  
> -    if (hmp_handle_error(mon, err)) {
> +    if (hmp_handle_error(hmp, err)) {
>          return;
>      }
>  
> @@ -86,13 +86,12 @@ void hmp_info_network(MonitorHMP *hmp, const QDict *qdict)
>  
>  void hmp_set_link(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *name = qdict_get_str(qdict, "name");
>      bool up = qdict_get_bool(qdict, "up");
>      Error *err = NULL;
>  
>      qmp_set_link(name, up, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  
> @@ -113,7 +112,6 @@ void hmp_announce_self(MonitorHMP *hmp, const QDict *qdict)
>  
>  void hmp_netdev_add(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      QemuOpts *opts;
>      const char *type = qdict_get_try_str(qdict, "type");
> @@ -133,17 +131,16 @@ void hmp_netdev_add(MonitorHMP *hmp, const QDict *qdict)
>      }
>  
>  out:
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_netdev_del(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *id = qdict_get_str(qdict, "id");
>      Error *err = NULL;
>  
>      qmp_netdev_del(id, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  
> diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c
> index 16847d1ce261..2e2eb33371e2 100644
> --- a/qom/qom-hmp-cmds.c
> +++ b/qom/qom-hmp-cmds.c
> @@ -42,12 +42,11 @@ void hmp_qom_list(MonitorHMP *hmp, const QDict *qdict)
>          }
>          qapi_free_ObjectPropertyInfoList(start);
>      }
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_qom_set(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const bool json = qdict_get_try_bool(qdict, "json", false);
>      const char *path = qdict_get_str(qdict, "path");
>      const char *property = qdict_get_str(qdict, "property");
> @@ -71,7 +70,7 @@ void hmp_qom_set(MonitorHMP *hmp, const QDict *qdict)
>          }
>      }
>  
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_qom_get(MonitorHMP *hmp, const QDict *qdict)
> @@ -89,7 +88,7 @@ void hmp_qom_get(MonitorHMP *hmp, const QDict *qdict)
>      }
>  
>      qobject_unref(obj);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  typedef struct QOMCompositionState {
> @@ -160,22 +159,20 @@ void hmp_info_qom_tree(MonitorHMP *hmp, const QDict *dict)
>  
>  void hmp_object_add(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *options = qdict_get_str(qdict, "object");
>      Error *err = NULL;
>  
>      user_creatable_add_from_str(options, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_object_del(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *id = qdict_get_str(qdict, "id");
>      Error *err = NULL;
>  
>      user_creatable_del(id, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void object_add_completion(ReadLineState *rs, int nb_args, const char *str)
> diff --git a/system/dirtylimit-hmp-cmds.c b/system/dirtylimit-hmp-cmds.c
> index 4c100783778f..75194add7931 100644
> --- a/system/dirtylimit-hmp-cmds.c
> +++ b/system/dirtylimit-hmp-cmds.c
> @@ -23,7 +23,7 @@ void hmp_cancel_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
>  
>      qmp_cancel_vcpu_dirty_limit(!!(cpu_index != -1), cpu_index, &err);
>      if (err) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>  
> @@ -33,7 +33,6 @@ void hmp_cancel_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
>  
>  void hmp_set_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      int64_t dirty_rate = qdict_get_int(qdict, "dirty_rate");
>      int64_t cpu_index = qdict_get_try_int(qdict, "cpu_index", -1);
>      Error *err = NULL;
> @@ -46,7 +45,7 @@ void hmp_set_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
>      qmp_set_vcpu_dirty_limit(!!(cpu_index != -1), cpu_index, dirty_rate, &err);
>  
>  out:
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_info_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
> @@ -63,7 +62,7 @@ void hmp_info_vcpu_dirty_limit(MonitorHMP *hmp, const QDict *qdict)
>  
>      head = qmp_query_vcpu_dirty_limit(&err);
>      if (err) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>  
> diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
> index e27b9724867a..5c2de2f53cc9 100644
> --- a/system/qdev-monitor.c
> +++ b/system/qdev-monitor.c
> @@ -1004,7 +1004,6 @@ void qmp_device_sync_config(const char *id, Error **errp)
>  
>  void hmp_device_add(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      QemuOpts *opts;
>      DeviceState *dev;
> @@ -1034,17 +1033,16 @@ void hmp_device_add(MonitorHMP *hmp, const QDict *qdict)
>      }
>      object_unref(dev);
>  out:
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_device_del(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *id = qdict_get_str(qdict, "id");
>      Error *err = NULL;
>  
>      qmp_device_del(id, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
> diff --git a/system/runstate-hmp-cmds.c b/system/runstate-hmp-cmds.c
> index 834b95835339..051ee45ee74c 100644
> --- a/system/runstate-hmp-cmds.c
> +++ b/system/runstate-hmp-cmds.c
> @@ -70,7 +70,6 @@ void hmp_one_insn_per_tb(MonitorHMP *hmp, const QDict *qdict)
>  
>  void hmp_watchdog_action(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      WatchdogAction action;
>      char *qapi_value;
> @@ -79,7 +78,7 @@ void hmp_watchdog_action(MonitorHMP *hmp, const QDict *qdict)
>      action = qapi_enum_parse(&WatchdogAction_lookup, qapi_value, -1, &err);
>      g_free(qapi_value);
>      if (err) {
> -        hmp_handle_error(mon, err);
> +        hmp_handle_error(hmp, err);
>          return;
>      }
>      qmp_watchdog_set_action(action, &error_abort);
> diff --git a/target/i386/monitor.c b/target/i386/monitor.c
> index f1d2a327ddad..f68dd38ac225 100644
> --- a/target/i386/monitor.c
> +++ b/target/i386/monitor.c
> @@ -573,7 +573,6 @@ void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
>  
>  void hmp_mce(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      X86CPU *cpu;
>      CPUState *cs;
>      int cpu_index = qdict_get_int(qdict, "cpu_index");
> @@ -596,5 +595,5 @@ void hmp_mce(MonitorHMP *hmp, const QDict *qdict)
>      } else {
>          error_setg(&err, "Invalid CPU %d", cpu_index);
>      }
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
> diff --git a/ui/ui-hmp-cmds.c b/ui/ui-hmp-cmds.c
> index 5f3522943c56..186209fd0234 100644
> --- a/ui/ui-hmp-cmds.c
> +++ b/ui/ui-hmp-cmds.c
> @@ -73,11 +73,10 @@ void hmp_mouse_button(MonitorHMP *hmp, const QDict *qdict)
>  
>  void hmp_mouse_set(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>  
>      qemu_mouse_set(qdict_get_int(qdict, "index"), &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_info_mice(MonitorHMP *hmp, const QDict *qdict)
> @@ -158,7 +157,7 @@ void hmp_info_vnc(MonitorHMP *hmp, const QDict *qdict)
>  
>      info2l = qmp_query_vnc_servers(&err);
>      info2l_head = info2l;
> -    if (hmp_handle_error(mon, err)) {
> +    if (hmp_handle_error(hmp, err)) {
>          return;
>      }
>      if (!info2l) {
> @@ -266,7 +265,6 @@ out:
>  
>  void hmp_set_password(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *protocol  = qdict_get_str(qdict, "protocol");
>      const char *password  = qdict_get_str(qdict, "password");
>      const char *display = qdict_get_try_str(qdict, "display");
> @@ -297,12 +295,11 @@ void hmp_set_password(MonitorHMP *hmp, const QDict *qdict)
>      qmp_set_password(&opts, &err);
>  
>  out:
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  void hmp_expire_password(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *protocol  = qdict_get_str(qdict, "protocol");
>      const char *whenstr = qdict_get_str(qdict, "time");
>      const char *display = qdict_get_try_str(qdict, "display");
> @@ -325,7 +322,7 @@ void hmp_expire_password(MonitorHMP *hmp, const QDict *qdict)
>      qmp_expire_password(&opts, &err);
>  
>  out:
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  
>  #ifdef CONFIG_VNC
> @@ -427,7 +424,7 @@ void hmp_sendkey(MonitorHMP *hmp, const QDict *qdict)
>      }
>  
>      qmp_send_key(head, has_hold_time, hold_time, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  
>  out:
>      qapi_free_KeyValue(v);
> @@ -465,7 +462,6 @@ void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
>  void coroutine_fn
>  hmp_screendump(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      const char *filename = qdict_get_str(qdict, "filename");
>      const char *id = qdict_get_try_str(qdict, "device");
>      int64_t head = qdict_get_try_int(qdict, "head", 0);
> @@ -482,13 +478,12 @@ hmp_screendump(MonitorHMP *hmp, const QDict *qdict)
>      qmp_screendump(filename, id, id != NULL, head,
>                     input_format != NULL, format, &err);
>  end:
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
>  #endif
>  
>  void hmp_client_migrate_info(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      Error *err = NULL;
>      const char *protocol = qdict_get_str(qdict, "protocol");
>      const char *hostname = qdict_get_str(qdict, "hostname");
> @@ -501,5 +496,5 @@ void hmp_client_migrate_info(MonitorHMP *hmp, const QDict *qdict)
>      qmp_client_migrate_info(protocol, hostname,
>                              has_port, port, has_tls_port, tls_port,
>                              cert_subject, &err);
> -    hmp_handle_error(mon, err);
> +    hmp_handle_error(hmp, err);
>  }
> 
> -- 
> 2.55.0.543.g5ebe2ebe4ea8
> 
-- 
 -----Open up your eyes, open up your mind, open up your code -------   
/ Dr. David Alan Gilbert    |       Running GNU/Linux       | Happy  \ 
\        dave @ treblig.org |                               | In Hex /
 \ _________________________|_____ http://www.treblig.org   |_______/


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

* Re: [PATCH v3 33/49] monitor: add monitor_cur_hmp() helper
  2026-08-16 19:13 ` [PATCH v3 33/49] monitor: add monitor_cur_hmp() helper Marc-André Lureau
@ 2026-08-17  0:49   ` Dr. David Alan Gilbert
  0 siblings, 0 replies; 73+ messages in thread
From: Dr. David Alan Gilbert @ 2026-08-17  0:49 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Paolo Bonzini

* Marc-André Lureau (marcandre.lureau@redhat.com) wrote:
> This will help to simplify the code in the following changes.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Dr. David Alan Gilbert <dave@treblig.org>

> ---
>  include/monitor/hmp.h |  2 ++
>  monitor/hmp.c         | 10 ++++++++++
>  stubs/meson.build     |  1 +
>  stubs/monitor-hmp.c   |  9 +++++++++
>  4 files changed, 22 insertions(+)
> 
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index 827a56144824..6aa562ddbaa2 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -36,6 +36,8 @@ struct MonitorDef {
>  void monitor_new_hmp(const char *id, const char *chardev_id,
>                       bool use_readline, Error **errp);
>  
> +MonitorHMP *monitor_cur_hmp(void);
> +
>  int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
>      G_GNUC_PRINTF(2, 0);
>  int monitor_printf(Monitor *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
> diff --git a/monitor/hmp.c b/monitor/hmp.c
> index 57c4127641ac..47fb7cef6de2 100644
> --- a/monitor/hmp.c
> +++ b/monitor/hmp.c
> @@ -47,6 +47,16 @@
>  
>  OBJECT_DEFINE_TYPE(MonitorHMP, monitor_hmp, MONITOR_HMP, MONITOR);
>  
> +MonitorHMP *monitor_cur_hmp(void)
> +{
> +    Monitor *mon = monitor_cur();
> +    if (mon) {
> +        return (MonitorHMP *)object_dynamic_cast(OBJECT(mon),
> +                                                 TYPE_MONITOR_HMP);
> +    }
> +    return NULL;
> +}
> +
>  static void monitor_hmp_finalize(Object *obj)
>  {
>      MonitorHMP *hmp = MONITOR_HMP(obj);
> diff --git a/stubs/meson.build b/stubs/meson.build
> index 3b2f2680b193..7e15687a62b7 100644
> --- a/stubs/meson.build
> +++ b/stubs/meson.build
> @@ -7,6 +7,7 @@ stub_ss.add(files('fdset.c'))
>  stub_ss.add(files('iothread-lock.c'))
>  stub_ss.add(files('is-daemonized.c'))
>  stub_ss.add(files('monitor-core.c'))
> +stub_ss.add(files('monitor-hmp.c'))
>  stub_ss.add(files('replay-mode.c'))
>  stub_ss.add(files('trace-control.c'))
>  
> diff --git a/stubs/monitor-hmp.c b/stubs/monitor-hmp.c
> new file mode 100644
> index 000000000000..9452a3f0c2c8
> --- /dev/null
> +++ b/stubs/monitor-hmp.c
> @@ -0,0 +1,9 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +#include "qemu/osdep.h"
> +#include "monitor/hmp.h"
> +
> +MonitorHMP *monitor_cur_hmp(void)
> +{
> +    return NULL;
> +}
> 
> -- 
> 2.55.0.543.g5ebe2ebe4ea8
> 
-- 
 -----Open up your eyes, open up your mind, open up your code -------   
/ Dr. David Alan Gilbert    |       Running GNU/Linux       | Happy  \ 
\        dave @ treblig.org |                               | In Hex /
 \ _________________________|_____ http://www.treblig.org   |_______/


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

* Re: [PATCH v3 44/49] hexagon: condition HMP-specific code
  2026-08-16 19:13 ` [PATCH v3 44/49] hexagon: condition HMP-specific code Marc-André Lureau
@ 2026-08-17  3:46   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 73+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-17  3:46 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Brian Cain, Pierrick Bouvier

On 16/8/26 21:13, Marc-André Lureau wrote:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   hw/hexagon/hexagon_tlb.c | 42 ++++++++++++++++++++++--------------------
>   target/hexagon/hex_mmu.c |  2 ++
>   2 files changed, 24 insertions(+), 20 deletions(-)

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


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

* Re: [PATCH v3 42/49] target: guard MonitorDef tables with CONFIG_HMP
  2026-08-16 19:13 ` [PATCH v3 42/49] target: guard MonitorDef tables " Marc-André Lureau
@ 2026-08-17  3:47   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 73+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-17  3:47 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Dr. David Alan Gilbert, Paolo Bonzini,
	Zhao Liu, Laurent Vivier, Mark Cave-Ayland, Artyom Tarasenko

On 16/8/26 21:13, Marc-André Lureau wrote:
> 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.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   include/hw/core/sysemu-cpu-ops.h | 2 ++
>   monitor/hmp.c                    | 4 +++-
>   target/i386/cpu.c                | 4 ++++
>   target/m68k/cpu.c                | 4 ++++
>   target/sparc/cpu.c               | 5 +++--
>   5 files changed, 16 insertions(+), 3 deletions(-)

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


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

* Re: [PATCH v3 39/49] qdev-monitor: make print_dev() callback take MonitorHMP
  2026-08-16 19:13 ` [PATCH v3 39/49] qdev-monitor: make print_dev() callback " Marc-André Lureau
@ 2026-08-17  3:48   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 73+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-17  3:48 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Michael S. Tsirkin, Laurent Vivier, Amit Shah,
	Paolo Bonzini, Stefano Stabellini, Anthony PERARD,
	Edgar E. Iglesias, xen-devel

On 16/8/26 21:13, Marc-André Lureau wrote:
> The callback is specific to HMP context, avoid unsafe MONITOR_HMP()
> cast.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   hw/char/virtio-serial-bus.c | 6 +++---
>   hw/core/sysbus.c            | 5 ++---
>   hw/misc/auxbus.c            | 7 +++----
>   hw/pci/pci-hmp-cmds.c       | 3 +--
>   hw/pci/pci-internal.h       | 2 +-
>   hw/usb/bus.c                | 5 ++---
>   hw/xen/xen-bus.c            | 3 +--
>   include/hw/core/qdev.h      | 3 ++-
>   system/qdev-monitor.c       | 7 +++----
>   9 files changed, 18 insertions(+), 23 deletions(-)

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


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

* Re: [PATCH v3 38/49] hexagon: make dump_mmu() take MonitorHMP
  2026-08-16 19:13 ` [PATCH v3 38/49] hexagon: make dump_mmu() take MonitorHMP Marc-André Lureau
@ 2026-08-17  3:49   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 73+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-17  3:49 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Brian Cain, Pierrick Bouvier

On 16/8/26 21:13, Marc-André Lureau wrote:
> Avoid unsafe MONITOR_HMP() casts.
> 
> The function has no caller since its introduction and could
> be dropped if it is not wired to a HMP command.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   hw/hexagon/hexagon_tlb.c         | 8 +++-----
>   include/hw/hexagon/hexagon_tlb.h | 5 +++--
>   target/hexagon/hex_mmu.c         | 4 ++--
>   target/hexagon/hex_mmu.h         | 3 ++-
>   4 files changed, 10 insertions(+), 10 deletions(-)

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


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

* Re: [PATCH v3 03/49] hmp: fix snapshot_blkdev argument type
  2026-08-16 19:12 ` [PATCH v3 03/49] hmp: fix snapshot_blkdev argument type Marc-André Lureau
@ 2026-08-17  3:51   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 73+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-17  3:51 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Kevin Wolf, Hanna Reitz,
	Dr. David Alan Gilbert, qemu-block

On 16/8/26 21:12, Marc-André Lureau wrote:
> The `snapshot-file` argument for `snapshot_blkdev` is mandatory. Correct
> the `args_type` definition to reflect this.
> 
> Fixes: 6106e2492fe ("qapi: Convert blockdev_snapshot_sync")
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   block/monitor/block-hmp-cmds.c | 12 +-----------
>   hmp-commands.hx                |  2 +-
>   2 files changed, 2 insertions(+), 12 deletions(-)

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


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

* Re: [PATCH v3 07/49] system: decouple qmp_inject_nmi() from Monitor
  2026-08-16 19:12 ` [PATCH v3 07/49] system: decouple qmp_inject_nmi() from Monitor Marc-André Lureau
@ 2026-08-17  3:53   ` Philippe Mathieu-Daudé
  2026-08-17  8:04     ` Marc-André Lureau
  0 siblings, 1 reply; 73+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-17  3:53 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Eric Blake, Zhao Liu

On 16/8/26 21:12, Marc-André Lureau wrote:
> Use first_cpu directly instead of going through monitor_get_cpu_index(),
> as this is HMP-territory. QMP doesn't have a `cpu` command, we should
> add arguments instead when needed.
> 
> Update the inject-nmi doc to accurately describe per-architecture NMI
> delivery.
> 
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   qapi/machine.json | 8 ++++----
>   1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 2d63c1bac3b4..29ab1cb9d7f4 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -432,10 +432,10 @@
>   ##
>   # @inject-nmi:
>   #
> -# Injects a Non-Maskable Interrupt (machine specific: for example on
> -# s390x CCW only the first vCPU receives the NMI, but on x86 machines
> -# all vCPUs receive it).  The command fails when the guest doesn't
> -# support injecting.
> +# Injects a Non-Maskable Interrupt into the virtual machine.  The NMI
> +# is delivered to all vCPUs (x86, hppa, ppc64) or to the first vCPU
> +# (s390).  The command fails when the guest doesn't support
> +# injecting.

You can drop this one.


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

* Re: [PATCH v3 13/49] tests/qtest/qmp-test: don't depend on human-monitor-command
  2026-08-16 19:12 ` [PATCH v3 13/49] tests/qtest/qmp-test: don't depend on human-monitor-command Marc-André Lureau
@ 2026-08-17  3:55   ` Philippe Mathieu-Daudé
  2026-08-17  8:11     ` Marc-André Lureau
  0 siblings, 1 reply; 73+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-17  3:55 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Fabiano Rosas, Laurent Vivier, Paolo Bonzini

On 16/8/26 21:12, Marc-André Lureau wrote:
> The test was using 'human-monitor-command' (which requires HMP) to
> verify that an integer 'id' is echoed back on failure. Replace with
> 'query-name' for the success case and 'block_resize' (missing
> required args) for the failure case, so the test works regardless of
> HMP availability.
> 
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   tests/qtest/qmp-test.c | 13 +++++++++++--
>   1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/tests/qtest/qmp-test.c b/tests/qtest/qmp-test.c
> index 3a325a04e07b..927ab053f8ab 100644
> --- a/tests/qtest/qmp-test.c
> +++ b/tests/qtest/qmp-test.c
> @@ -151,9 +151,14 @@ static void test_qmp_protocol(void)
>       g_assert_cmpstr(qdict_get_try_str(resp, "id"), ==, "cookie#1");
>       qobject_unref(resp);
>   
> -    /* Test command failure with 'id' */
> -    resp = qtest_qmp(qts, "{ 'execute': 'human-monitor-command', 'id': 2 }");
> +    /* Test integer 'id' is echoed back on success */
> +    resp = qtest_qmp(qts, "{ 'execute': 'query-name', 'id': 2 }");
>       g_assert_cmpint(qdict_get_int(resp, "id"), ==, 2);
> +    qobject_unref(resp);
> +
> +    /* Test integer 'id' is echoed back on failure */
> +    resp = qtest_qmp(qts, "{ 'execute': 'block_resize', 'id': 3 }");
> +    g_assert_cmpint(qdict_get_int(resp, "id"), ==, 3);
>       qmp_expect_error_and_unref(resp, "GenericError");
>   
>       qtest_quit(qts);
> @@ -487,6 +492,7 @@ static void test_qmp_monitor_remove_cli(void)
>       qtest_quit(qts);
>   }
>   
> +#ifdef CONFIG_HMP
>   static void test_qmp_monitor_remove_hmp(void)
>   {
>       QTestState *qts;
> @@ -504,6 +510,7 @@ static void test_qmp_monitor_remove_hmp(void)
>   
>       qtest_quit(qts);
>   }
> +#endif
>   
>   int main(int argc, char *argv[])
>   {
> @@ -521,7 +528,9 @@ int main(int argc, char *argv[])
>       qtest_add_func("qmp/monitor-chardev-in-use",
>                       test_qmp_monitor_chardev_in_use);
>       qtest_add_func("qmp/monitor-remove-cli", test_qmp_monitor_remove_cli);
> +#ifdef CONFIG_HMP
>       qtest_add_func("qmp/monitor-remove-hmp", test_qmp_monitor_remove_hmp);
> +#endif

Should we re-order #26 "build-sys: add 'hmp' option" or add a temporary
#define CONFIG_HMP?


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

* Re: [PATCH v3 11/49] python, tests: switch usernet queries from HMP to QMP
  2026-08-16 19:12 ` [PATCH v3 11/49] python, tests: switch usernet queries from HMP to QMP Marc-André Lureau
@ 2026-08-17  7:30   ` Thomas Huth
  2026-08-17  8:07     ` Marc-André Lureau
  0 siblings, 1 reply; 73+ messages in thread
From: Thomas Huth @ 2026-08-17  7:30 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, John Snow, Cleber Rosa, Thomas Huth,
	Alex Bennée, Pierrick Bouvier

On 16/08/2026 21.12, Marc-André Lureau wrote:
> Replace human-monitor-command "info usernet" calls with the structured
> x-query-usernet QMP command in get_usernet_hostfwd_port() and the VM
> test runner boot path.
> 
> Since x-query-usernet returns a list of UsernetInfo entries, callers
> now iterate over the result and extract the port from each entry's
> "info" field. Also switch get_info_usernet_hostfwd_port() from
> split('\r\n') to splitlines(), since QMP strings use \n rather than
> the HMP monitor's \r\n line endings.
> 
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
> Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
> ---
>   python/qemu/utils/__init__.py       |  5 +++--
>   tests/functional/qemu_test/utils.py |  8 ++++++--
>   tests/vm/basevm.py                  | 13 ++++++++-----
>   3 files changed, 17 insertions(+), 9 deletions(-)
> 
> diff --git a/python/qemu/utils/__init__.py b/python/qemu/utils/__init__.py
> index be5daa836340..e32911d4c6df 100644
> --- a/python/qemu/utils/__init__.py
> +++ b/python/qemu/utils/__init__.py
> @@ -46,10 +46,11 @@ def get_info_usernet_hostfwd_port(info_usernet_output: str) -> Optional[int]:
>       """
>       Returns the port given to the hostfwd parameter via info usernet
>   
> -    :param info_usernet_output: output generated by hmp command "info usernet"
> +    :param info_usernet_output: output generated by "info usernet" or
> +        the "info" field from x-query-usernet
>       :return: the port number allocated by the hostfwd option
>       """
> -    for line in info_usernet_output.split('\r\n'):
> +    for line in info_usernet_output.splitlines():
>           regex = r'TCP.HOST_FORWARD.*127\.0\.0\.1\s+(\d+)\s+10\.'
>           match = re.search(regex, line)
>           if match is not None:
> diff --git a/tests/functional/qemu_test/utils.py b/tests/functional/qemu_test/utils.py
> index 826c267785bd..0992db49ab28 100644
> --- a/tests/functional/qemu_test/utils.py
> +++ b/tests/functional/qemu_test/utils.py
> @@ -14,8 +14,12 @@
>   
>   
>   def get_usernet_hostfwd_port(vm):
> -    res = vm.cmd('human-monitor-command', command_line='info usernet')
> -    return get_info_usernet_hostfwd_port(res)
> +    res = vm.cmd('x-query-usernet')
> +    for entry in res:
> +        port = get_info_usernet_hostfwd_port(entry['info'])
> +        if port is not None:
> +            return port
> +    return None
>   
>   def pow2ceil(x):
>       """
> diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
> index 9e879e966a36..198b04e8c375 100644
> --- a/tests/vm/basevm.py
> +++ b/tests/vm/basevm.py
> @@ -312,12 +312,15 @@ def boot(self, img, extra_args=[]):
>           self._guest = guest
>           # Init console so we can start consuming the chars.
>           self.console_init()
> -        usernet_info = guest.cmd("human-monitor-command",
> -                                 command_line="info usernet")
> -        self.ssh_port = get_info_usernet_hostfwd_port(usernet_info)
> +        res = guest.cmd("x-query-usernet")
> +        for entry in res:
> +            port = get_info_usernet_hostfwd_port(entry['info'])
> +            if port is not None:
> +                self.ssh_port = port
> +                break
>           if not self.ssh_port:
> -            raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
> -                            usernet_info)
> +            raise Exception("Cannot find ssh port from"
> +                            " 'x-query-usernet': %s" % res)
>   
>       def console_init(self, timeout = None):
>           if timeout == None:
While you're at it, may I suggest to move the cmd('x-query-usernet') into 
the get_info_usernet_hostfwd_port() function in 
python/qemu/utils/__init__.py, too, so that the callers don't have to take 
care about this anymore? Also just return the port number from there, so 
that the callers don't have to take care about the parsing. WDYT?

  Thomas



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

* Re: [PATCH v3 07/49] system: decouple qmp_inject_nmi() from Monitor
  2026-08-17  3:53   ` Philippe Mathieu-Daudé
@ 2026-08-17  8:04     ` Marc-André Lureau
  0 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-17  8:04 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: qemu-devel, Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Eric Blake, Zhao Liu

On Mon, Aug 17, 2026 at 7:53 AM Philippe Mathieu-Daudé
<philmd@oss.qualcomm.com> wrote:
>
> On 16/8/26 21:12, Marc-André Lureau wrote:
> > Use first_cpu directly instead of going through monitor_get_cpu_index(),
> > as this is HMP-territory. QMP doesn't have a `cpu` command, we should
> > add arguments instead when needed.
> >
> > Update the inject-nmi doc to accurately describe per-architecture NMI
> > delivery.
> >
> > Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> >   qapi/machine.json | 8 ++++----
> >   1 file changed, 4 insertions(+), 4 deletions(-)
> >
> > diff --git a/qapi/machine.json b/qapi/machine.json
> > index 2d63c1bac3b4..29ab1cb9d7f4 100644
> > --- a/qapi/machine.json
> > +++ b/qapi/machine.json
> > @@ -432,10 +432,10 @@
> >   ##
> >   # @inject-nmi:
> >   #
> > -# Injects a Non-Maskable Interrupt (machine specific: for example on
> > -# s390x CCW only the first vCPU receives the NMI, but on x86 machines
> > -# all vCPUs receive it).  The command fails when the guest doesn't
> > -# support injecting.
> > +# Injects a Non-Maskable Interrupt into the virtual machine.  The NMI
> > +# is delivered to all vCPUs (x86, hppa, ppc64) or to the first vCPU
> > +# (s390).  The command fails when the guest doesn't support
> > +# injecting.
>
> You can drop this one.

ack



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

* Re: [PATCH v3 11/49] python, tests: switch usernet queries from HMP to QMP
  2026-08-17  7:30   ` Thomas Huth
@ 2026-08-17  8:07     ` Marc-André Lureau
  0 siblings, 0 replies; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-17  8:07 UTC (permalink / raw)
  To: Thomas Huth
  Cc: qemu-devel, Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, John Snow, Cleber Rosa, Thomas Huth,
	Alex Bennée, Pierrick Bouvier

Hi

On Mon, Aug 17, 2026 at 11:31 AM Thomas Huth <th.huth@posteo.de> wrote:
>
> On 16/08/2026 21.12, Marc-André Lureau wrote:
> > Replace human-monitor-command "info usernet" calls with the structured
> > x-query-usernet QMP command in get_usernet_hostfwd_port() and the VM
> > test runner boot path.
> >
> > Since x-query-usernet returns a list of UsernetInfo entries, callers
> > now iterate over the result and extract the port from each entry's
> > "info" field. Also switch get_info_usernet_hostfwd_port() from
> > split('\r\n') to splitlines(), since QMP strings use \n rather than
> > the HMP monitor's \r\n line endings.
> >
> > Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
> > Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
> > ---
> >   python/qemu/utils/__init__.py       |  5 +++--
> >   tests/functional/qemu_test/utils.py |  8 ++++++--
> >   tests/vm/basevm.py                  | 13 ++++++++-----
> >   3 files changed, 17 insertions(+), 9 deletions(-)
> >
> > diff --git a/python/qemu/utils/__init__.py b/python/qemu/utils/__init__.py
> > index be5daa836340..e32911d4c6df 100644
> > --- a/python/qemu/utils/__init__.py
> > +++ b/python/qemu/utils/__init__.py
> > @@ -46,10 +46,11 @@ def get_info_usernet_hostfwd_port(info_usernet_output: str) -> Optional[int]:
> >       """
> >       Returns the port given to the hostfwd parameter via info usernet
> >
> > -    :param info_usernet_output: output generated by hmp command "info usernet"
> > +    :param info_usernet_output: output generated by "info usernet" or
> > +        the "info" field from x-query-usernet
> >       :return: the port number allocated by the hostfwd option
> >       """
> > -    for line in info_usernet_output.split('\r\n'):
> > +    for line in info_usernet_output.splitlines():
> >           regex = r'TCP.HOST_FORWARD.*127\.0\.0\.1\s+(\d+)\s+10\.'
> >           match = re.search(regex, line)
> >           if match is not None:
> > diff --git a/tests/functional/qemu_test/utils.py b/tests/functional/qemu_test/utils.py
> > index 826c267785bd..0992db49ab28 100644
> > --- a/tests/functional/qemu_test/utils.py
> > +++ b/tests/functional/qemu_test/utils.py
> > @@ -14,8 +14,12 @@
> >
> >
> >   def get_usernet_hostfwd_port(vm):
> > -    res = vm.cmd('human-monitor-command', command_line='info usernet')
> > -    return get_info_usernet_hostfwd_port(res)
> > +    res = vm.cmd('x-query-usernet')
> > +    for entry in res:
> > +        port = get_info_usernet_hostfwd_port(entry['info'])
> > +        if port is not None:
> > +            return port
> > +    return None
> >
> >   def pow2ceil(x):
> >       """
> > diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
> > index 9e879e966a36..198b04e8c375 100644
> > --- a/tests/vm/basevm.py
> > +++ b/tests/vm/basevm.py
> > @@ -312,12 +312,15 @@ def boot(self, img, extra_args=[]):
> >           self._guest = guest
> >           # Init console so we can start consuming the chars.
> >           self.console_init()
> > -        usernet_info = guest.cmd("human-monitor-command",
> > -                                 command_line="info usernet")
> > -        self.ssh_port = get_info_usernet_hostfwd_port(usernet_info)
> > +        res = guest.cmd("x-query-usernet")
> > +        for entry in res:
> > +            port = get_info_usernet_hostfwd_port(entry['info'])
> > +            if port is not None:
> > +                self.ssh_port = port
> > +                break
> >           if not self.ssh_port:
> > -            raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
> > -                            usernet_info)
> > +            raise Exception("Cannot find ssh port from"
> > +                            " 'x-query-usernet': %s" % res)
> >
> >       def console_init(self, timeout = None):
> >           if timeout == None:
> While you're at it, may I suggest to move the cmd('x-query-usernet') into
> the get_info_usernet_hostfwd_port() function in
> python/qemu/utils/__init__.py, too, so that the callers don't have to take
> care about this anymore? Also just return the port number from there, so
> that the callers don't have to take care about the parsing. WDYT?

Good idea, but not so simple. qemu/utils doesn't depend on any VM/QMP
types.. we could use duck typing or other solution. I would rather
defer this for now

thanks


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

* Re: [PATCH v3 13/49] tests/qtest/qmp-test: don't depend on human-monitor-command
  2026-08-17  3:55   ` Philippe Mathieu-Daudé
@ 2026-08-17  8:11     ` Marc-André Lureau
  2026-08-17  9:11       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 73+ messages in thread
From: Marc-André Lureau @ 2026-08-17  8:11 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: qemu-devel, Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Fabiano Rosas, Laurent Vivier, Paolo Bonzini

Hi

On Mon, Aug 17, 2026 at 7:56 AM Philippe Mathieu-Daudé
<philmd@oss.qualcomm.com> wrote:
>
> On 16/8/26 21:12, Marc-André Lureau wrote:
> > The test was using 'human-monitor-command' (which requires HMP) to
> > verify that an integer 'id' is echoed back on failure. Replace with
> > 'query-name' for the success case and 'block_resize' (missing
> > required args) for the failure case, so the test works regardless of
> > HMP availability.
> >
> > Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> >   tests/qtest/qmp-test.c | 13 +++++++++++--
> >   1 file changed, 11 insertions(+), 2 deletions(-)
> >
> > diff --git a/tests/qtest/qmp-test.c b/tests/qtest/qmp-test.c
> > index 3a325a04e07b..927ab053f8ab 100644
> > --- a/tests/qtest/qmp-test.c
> > +++ b/tests/qtest/qmp-test.c
> > @@ -151,9 +151,14 @@ static void test_qmp_protocol(void)
> >       g_assert_cmpstr(qdict_get_try_str(resp, "id"), ==, "cookie#1");
> >       qobject_unref(resp);
> >
> > -    /* Test command failure with 'id' */
> > -    resp = qtest_qmp(qts, "{ 'execute': 'human-monitor-command', 'id': 2 }");
> > +    /* Test integer 'id' is echoed back on success */
> > +    resp = qtest_qmp(qts, "{ 'execute': 'query-name', 'id': 2 }");
> >       g_assert_cmpint(qdict_get_int(resp, "id"), ==, 2);
> > +    qobject_unref(resp);
> > +
> > +    /* Test integer 'id' is echoed back on failure */
> > +    resp = qtest_qmp(qts, "{ 'execute': 'block_resize', 'id': 3 }");
> > +    g_assert_cmpint(qdict_get_int(resp, "id"), ==, 3);
> >       qmp_expect_error_and_unref(resp, "GenericError");
> >
> >       qtest_quit(qts);
> > @@ -487,6 +492,7 @@ static void test_qmp_monitor_remove_cli(void)
> >       qtest_quit(qts);
> >   }
> >
> > +#ifdef CONFIG_HMP
> >   static void test_qmp_monitor_remove_hmp(void)
> >   {
> >       QTestState *qts;
> > @@ -504,6 +510,7 @@ static void test_qmp_monitor_remove_hmp(void)
> >
> >       qtest_quit(qts);
> >   }
> > +#endif
> >
> >   int main(int argc, char *argv[])
> >   {
> > @@ -521,7 +528,9 @@ int main(int argc, char *argv[])
> >       qtest_add_func("qmp/monitor-chardev-in-use",
> >                       test_qmp_monitor_chardev_in_use);
> >       qtest_add_func("qmp/monitor-remove-cli", test_qmp_monitor_remove_cli);
> > +#ifdef CONFIG_HMP
> >       qtest_add_func("qmp/monitor-remove-hmp", test_qmp_monitor_remove_hmp);
> > +#endif
>
> Should we re-order #26 "build-sys: add 'hmp' option" or add a temporary
> #define CONFIG_HMP?

Let's add a temporary CONFIG_HMP, rather than a temporary non-working
--disable-hmp. That should also help with ordering of other later
patches which may not be optimal.


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

* Re: [PATCH v3 13/49] tests/qtest/qmp-test: don't depend on human-monitor-command
  2026-08-17  8:11     ` Marc-André Lureau
@ 2026-08-17  9:11       ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 73+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-17  9:11 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Fabiano Rosas, Laurent Vivier, Paolo Bonzini

On 17/8/26 10:11, Marc-André Lureau wrote:
> Hi
> 
> On Mon, Aug 17, 2026 at 7:56 AM Philippe Mathieu-Daudé
> <philmd@oss.qualcomm.com> wrote:
>>
>> On 16/8/26 21:12, Marc-André Lureau wrote:
>>> The test was using 'human-monitor-command' (which requires HMP) to
>>> verify that an integer 'id' is echoed back on failure. Replace with
>>> 'query-name' for the success case and 'block_resize' (missing
>>> required args) for the failure case, so the test works regardless of
>>> HMP availability.
>>>
>>> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>> ---
>>>    tests/qtest/qmp-test.c | 13 +++++++++++--
>>>    1 file changed, 11 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/tests/qtest/qmp-test.c b/tests/qtest/qmp-test.c
>>> index 3a325a04e07b..927ab053f8ab 100644
>>> --- a/tests/qtest/qmp-test.c
>>> +++ b/tests/qtest/qmp-test.c
>>> @@ -151,9 +151,14 @@ static void test_qmp_protocol(void)
>>>        g_assert_cmpstr(qdict_get_try_str(resp, "id"), ==, "cookie#1");
>>>        qobject_unref(resp);
>>>
>>> -    /* Test command failure with 'id' */
>>> -    resp = qtest_qmp(qts, "{ 'execute': 'human-monitor-command', 'id': 2 }");
>>> +    /* Test integer 'id' is echoed back on success */
>>> +    resp = qtest_qmp(qts, "{ 'execute': 'query-name', 'id': 2 }");
>>>        g_assert_cmpint(qdict_get_int(resp, "id"), ==, 2);
>>> +    qobject_unref(resp);
>>> +
>>> +    /* Test integer 'id' is echoed back on failure */
>>> +    resp = qtest_qmp(qts, "{ 'execute': 'block_resize', 'id': 3 }");
>>> +    g_assert_cmpint(qdict_get_int(resp, "id"), ==, 3);
>>>        qmp_expect_error_and_unref(resp, "GenericError");
>>>
>>>        qtest_quit(qts);
>>> @@ -487,6 +492,7 @@ static void test_qmp_monitor_remove_cli(void)
>>>        qtest_quit(qts);
>>>    }
>>>
>>> +#ifdef CONFIG_HMP
>>>    static void test_qmp_monitor_remove_hmp(void)
>>>    {
>>>        QTestState *qts;
>>> @@ -504,6 +510,7 @@ static void test_qmp_monitor_remove_hmp(void)
>>>
>>>        qtest_quit(qts);
>>>    }
>>> +#endif
>>>
>>>    int main(int argc, char *argv[])
>>>    {
>>> @@ -521,7 +528,9 @@ int main(int argc, char *argv[])
>>>        qtest_add_func("qmp/monitor-chardev-in-use",
>>>                        test_qmp_monitor_chardev_in_use);
>>>        qtest_add_func("qmp/monitor-remove-cli", test_qmp_monitor_remove_cli);
>>> +#ifdef CONFIG_HMP
>>>        qtest_add_func("qmp/monitor-remove-hmp", test_qmp_monitor_remove_hmp);
>>> +#endif
>>
>> Should we re-order #26 "build-sys: add 'hmp' option" or add a temporary
>> #define CONFIG_HMP?
> 
> Let's add a temporary CONFIG_HMP, rather than a temporary non-working
> --disable-hmp. That should also help with ordering of other later
> patches which may not be optimal.

LGTM.



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

* Re: [PATCH v3 31/49] monitor: change HMPCommand cmd to take MonitorHMP
  2026-08-16 21:51   ` Dr. David Alan Gilbert
@ 2026-08-17 18:08     ` Jason J. Herne
  0 siblings, 0 replies; 73+ messages in thread
From: Jason J. Herne @ 2026-08-17 18:08 UTC (permalink / raw)
  To: Dr. David Alan Gilbert, Marc-André Lureau
  Cc: qemu-devel, Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Gerd Hoffmann, Gonglei (Arei), zhenwei pi,
	Kevin Wolf, Hanna Reitz, Paolo Bonzini, Ani Sinha,
	David Woodhouse, Paul Durrant, Michael S. Tsirkin,
	Richard Henderson, Marcelo Tosatti, Mark Cave-Ayland, Jiri Pirko,
	Jason Wang, Halil Pasic, Christian Borntraeger, Ilya Leoshkevich,
	David Hildenbrand, Eric Farman, Matthew Rosato, Cornelia Huck,
	Samuel Thibault, Hyman Huang, Peter Xu, Fabiano Rosas,
	Alex Bennée, Stefan Berger, Zhao Liu, Laurent Vivier,
	Nicholas Piggin, Chinmay Rath, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Yoshinori Sato,
	Artyom Tarasenko, Max Filippov, Stefan Hajnoczi, qemu-block, kvm,
	qemu-ppc, qemu-s390x, qemu-riscv

On 8/16/26 5:51 PM, Dr. David Alan Gilbert wrote:
> * Marc-André Lureau (marcandre.lureau@redhat.com) wrote:
>> 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.
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> Reviewed-by: Dr. David Alan Gilbert <dave@treblig.org>
> 
>> ---
>> ...
>>   hw/s390x/s390-skeys.c           |   5 +-
>>   hw/s390x/s390-stattrib.c        |   6 +-
Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>

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

* Re: [PATCH v3 37/49] monitor: tighten monitor_printf*()
  2026-08-16 19:13 ` [PATCH v3 37/49] monitor: tighten monitor_printf*() Marc-André Lureau
@ 2026-08-17 18:09   ` Jason J. Herne
  0 siblings, 0 replies; 73+ messages in thread
From: Jason J. Herne @ 2026-08-17 18:09 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Gerd Hoffmann, Gonglei (Arei), zhenwei pi,
	Kevin Wolf, Hanna Reitz, Paolo Bonzini, Alex Bennée,
	Pierrick Bouvier, Ani Sinha, Laurent Vivier, Amit Shah,
	Michael S. Tsirkin, Brian Cain, David Woodhouse, Paul Durrant,
	Richard Henderson, Marcelo Tosatti, Mark Cave-Ayland, Jiri Pirko,
	Jason Wang, Halil Pasic, Christian Borntraeger, Cornelia Huck,
	Eric Farman, Matthew Rosato, Ilya Leoshkevich, David Hildenbrand,
	Stefano Stabellini, Anthony PERARD, Edgar E. Iglesias,
	Dr. David Alan Gilbert, Hyman Huang, Peter Xu, Fabiano Rosas,
	Samuel Thibault, Stefan Berger, Zhao Liu, Nicholas Piggin,
	Chinmay Rath, Glenn Miles, Harsh Prateek Bora, Palmer Dabbelt,
	Alistair Francis, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei,
	Chao Liu, Yoshinori Sato, Artyom Tarasenko, Max Filippov,
	Stefan Hajnoczi, qemu-block, kvm, qemu-ppc, qemu-s390x, xen-devel,
	qemu-riscv



On 8/16/26 3:13 PM, Marc-André Lureau wrote:
> 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.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> ...
>   hw/pci/pci-stub.c                       |   3 +-
>   hw/s390x/s390-skeys.c                   |   9 +-
>   hw/s390x/s390-stattrib.c                |  20 +--
Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>


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

* Re: [PATCH v3 41/49] Guard HMP command implementations with CONFIG_HMP
  2026-08-16 19:13 ` [PATCH v3 41/49] Guard HMP command implementations with CONFIG_HMP Marc-André Lureau
@ 2026-08-17 18:11   ` Jason J. Herne
  0 siblings, 0 replies; 73+ messages in thread
From: Jason J. Herne @ 2026-08-17 18:11 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Richard Henderson, Paolo Bonzini,
	David Woodhouse, Paul Durrant, Michael S. Tsirkin,
	Marcelo Tosatti, Mark Cave-Ayland, Halil Pasic,
	Christian Borntraeger, Eric Farman, Matthew Rosato,
	Ilya Leoshkevich, David Hildenbrand, Cornelia Huck, Gerd Hoffmann,
	Hyman Huang, Peter Xu, Fabiano Rosas, Dr. David Alan Gilbert,
	Samuel Thibault, Jason Wang, Alex Bennée, Zhao Liu,
	Laurent Vivier, Nicholas Piggin, Chinmay Rath, Glenn Miles,
	Harsh Prateek Bora, Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Yoshinori Sato,
	Artyom Tarasenko, Max Filippov, kvm, qemu-ppc, qemu-s390x,
	qemu-riscv



On 8/16/26 3:13 PM, Marc-André Lureau wrote:
> 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: Daniel P. Berrangé <berrange@redhat.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> ...
>   hw/s390x/s390-skeys.c     | 2 ++
>   hw/s390x/s390-stattrib.c  | 4 ++++
Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com>

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

* Re: [PATCH v3 36/49] monitor: tighten monitor_set_cpu()/get_cpu()
  2026-08-16 19:13 ` [PATCH v3 36/49] monitor: tighten monitor_set_cpu()/get_cpu() Marc-André Lureau
@ 2026-08-18 14:15   ` Dr. David Alan Gilbert
  0 siblings, 0 replies; 73+ messages in thread
From: Dr. David Alan Gilbert @ 2026-08-18 14:15 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Philippe Mathieu-Daudé, Daniel P. Berrangé,
	Markus Armbruster, Paolo Bonzini, Zhao Liu, Laurent Vivier,
	Nicholas Piggin, Chinmay Rath, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Yoshinori Sato,
	Mark Cave-Ayland, Artyom Tarasenko, Max Filippov, qemu-ppc,
	qemu-riscv

* Marc-André Lureau (marcandre.lureau@redhat.com) wrote:
> 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.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Reviewed-by: Dr. David Alan Gilbert <dave@treblig.org>

> ---
>  hw/core/machine-hmp-cmds.c |  4 ++--
>  include/monitor/hmp.h      |  7 +++---
>  include/monitor/monitor.h  |  1 -
>  monitor/hmp-cmds.c         | 53 ++++++++++++++++++++++------------------------
>  monitor/hmp.c              | 18 ++++++++--------
>  monitor/monitor-internal.h |  2 +-
>  monitor/qmp-cmds.c         |  2 +-
>  stats/stats-hmp-cmds.c     |  2 +-
>  target/i386/cpu-apic.c     |  2 +-
>  target/i386/cpu.c          |  4 ++--
>  target/i386/monitor.c      |  4 ++--
>  target/m68k/monitor.c      |  2 +-
>  target/ppc/monitor.c       |  2 +-
>  target/riscv/monitor.c     |  2 +-
>  target/sh4/monitor.c       |  2 +-
>  target/sparc/monitor.c     |  2 +-
>  target/xtensa/monitor.c    |  2 +-
>  17 files changed, 54 insertions(+), 57 deletions(-)
> 
> diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
> index 4e2f0c212b0d..702c798ccc56 100644
> --- a/hw/core/machine-hmp-cmds.c
> +++ b/hw/core/machine-hmp-cmds.c
> @@ -36,7 +36,7 @@ void hmp_info_cpus(MonitorHMP *hmp, const QDict *qdict)
>          g_autofree char *cpu_model = cpu_model_from_type(cpu->value->qom_type);
>          int active = ' ';
>  
> -        if (cpu->value->cpu_index == monitor_get_cpu_index(mon)) {
> +        if (cpu->value->cpu_index == monitor_hmp_get_cpu_index(hmp)) {
>              active = '*';
>          }
>  
> @@ -228,7 +228,7 @@ void hmp_memsave(MonitorHMP *hmp, const QDict *qdict)
>      const char *filename = qdict_get_str(qdict, "filename");
>      uint64_t addr = qdict_get_int(qdict, "val");
>      Error *err = NULL;
> -    int cpu_index = monitor_get_cpu_index(mon);
> +    int cpu_index = monitor_hmp_get_cpu_index(hmp);
>  
>      if (cpu_index < 0) {
>          monitor_printf(mon, "No CPU available\n");
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index 6aa562ddbaa2..3fd17048b319 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -30,7 +30,7 @@ OBJECT_DECLARE_TYPE(MonitorHMP, MonitorHMPClass, MONITOR_HMP);
>  struct MonitorDef {
>      const char *name;
>      int offset;
> -    int64_t (*get_value)(Monitor *mon, const MonitorDef *md, int offset);
> +    int64_t (*get_value)(MonitorHMP *hmp, const MonitorDef *md, int offset);
>  };
>  
>  void monitor_new_hmp(const char *id, const char *chardev_id,
> @@ -53,8 +53,9 @@ void monitor_register_hmp_info_hrt(const char *name,
>                                     HumanReadableText *(*handler)(Error **errp));
>  
>  
> -CPUArchState *mon_get_cpu_env(Monitor *mon);
> -CPUState *mon_get_cpu(Monitor *mon);
> +CPUArchState *monitor_hmp_get_cpu_env(MonitorHMP *hmp);
> +CPUState *monitor_hmp_get_cpu(MonitorHMP *hmp);
> +int monitor_hmp_get_cpu_index(MonitorHMP *hmp);
>  
>  bool hmp_handle_error(MonitorHMP *hmp, Error *err);
>  void hmp_help_cmd(Monitor *mon, const char *name);
> diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
> index 72a8f6ea5b4f..2a550aec023f 100644
> --- a/include/monitor/monitor.h
> +++ b/include/monitor/monitor.h
> @@ -39,7 +39,6 @@ int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp);
>  
>  int monitor_puts(Monitor *mon, const char *str);
>  void monitor_flush(Monitor *mon);
> -int monitor_get_cpu_index(Monitor *mon);
>  
>  int monitor_puts_locked(Monitor *mon, const char *str);
>  void monitor_flush_locked(Monitor *mon);
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index d1e7e4de6585..89cc19c2431d 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -182,10 +182,10 @@ void hmp_cpu(MonitorHMP *hmp, const QDict *qdict)
>      Monitor *mon = MONITOR(hmp);
>      int64_t cpu_index;
>  
> -    /* XXX: drop the monitor_set_cpu() usage when all HMP commands that
> +    /* XXX: drop the monitor_hmp_set_cpu() usage when all HMP commands that
>              use it are converted to the QAPI */
>      cpu_index = qdict_get_int(qdict, "index");
> -    if (monitor_set_cpu(mon, cpu_index) < 0) {
> +    if (monitor_hmp_set_cpu(hmp, cpu_index) < 0) {
>          monitor_printf(mon, "invalid CPU index\n");
>      }
>  }
> @@ -512,39 +512,37 @@ void hmp_dumpdtb(MonitorHMP *hmp, const QDict *qdict)
>  #endif
>  
>  /* Set the current CPU defined by the user. Callers must hold BQL. */
> -int monitor_set_cpu(Monitor *mon, int cpu_index)
> +int monitor_hmp_set_cpu(MonitorHMP *hmp, int cpu_index)
>  {
> -    MonitorHMP *hmp_mon = MONITOR_HMP(mon);
>      CPUState *cpu;
>  
>      cpu = qemu_get_cpu(cpu_index);
>      if (cpu == NULL) {
>          return -1;
>      }
> -    g_free(hmp_mon->mon_cpu_path);
> -    hmp_mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
> +    g_free(hmp->mon_cpu_path);
> +    hmp->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
>      return 0;
>  }
>  
>  /* Callers must hold BQL. */
> -static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize)
> +static CPUState *monitor_hmp_get_cpu_sync(MonitorHMP *hmp, bool synchronize)
>  {
> -    MonitorHMP *hmp_mon = MONITOR_HMP(mon);
>      CPUState *cpu = NULL;
>  
> -    if (hmp_mon->mon_cpu_path) {
> -        cpu = (CPUState *) object_resolve_path_type(hmp_mon->mon_cpu_path,
> +    if (hmp->mon_cpu_path) {
> +        cpu = (CPUState *) object_resolve_path_type(hmp->mon_cpu_path,
>                                                      TYPE_CPU, NULL);
>          if (!cpu) {
> -            g_free(hmp_mon->mon_cpu_path);
> -            hmp_mon->mon_cpu_path = NULL;
> +            g_free(hmp->mon_cpu_path);
> +            hmp->mon_cpu_path = NULL;
>          }
>      }
> -    if (!hmp_mon->mon_cpu_path) {
> +    if (!hmp->mon_cpu_path) {
>          if (!first_cpu) {
>              return NULL;
>          }
> -        monitor_set_cpu(mon, first_cpu->cpu_index);
> +        monitor_hmp_set_cpu(hmp, first_cpu->cpu_index);
>          cpu = first_cpu;
>      }
>      assert(cpu != NULL);
> @@ -554,21 +552,21 @@ static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize)
>      return cpu;
>  }
>  
> -CPUState *mon_get_cpu(Monitor *mon)
> +CPUState *monitor_hmp_get_cpu(MonitorHMP *hmp)
>  {
> -    return mon_get_cpu_sync(mon, true);
> +    return monitor_hmp_get_cpu_sync(hmp, true);
>  }
>  
> -CPUArchState *mon_get_cpu_env(Monitor *mon)
> +CPUArchState *monitor_hmp_get_cpu_env(MonitorHMP *hmp)
>  {
> -    CPUState *cs = mon_get_cpu(mon);
> +    CPUState *cs = monitor_hmp_get_cpu(hmp);
>  
>      return cs ? cpu_env(cs) : NULL;
>  }
>  
> -int monitor_get_cpu_index(Monitor *mon)
> +int monitor_hmp_get_cpu_index(MonitorHMP *hmp)
>  {
> -    CPUState *cs = mon_get_cpu_sync(mon, false);
> +    CPUState *cs = monitor_hmp_get_cpu_sync(hmp, false);
>  
>      return cs ? cs->cpu_index : UNASSIGNED_CPU_INDEX;
>  }
> @@ -586,7 +584,7 @@ void hmp_info_registers(MonitorHMP *hmp, const QDict *qdict)
>              cpu_dump_state(cs, NULL, CPU_DUMP_FPU | CPU_DUMP_VPU);
>          }
>      } else {
> -        cs = vcpu >= 0 ? qemu_get_cpu(vcpu) : mon_get_cpu(mon);
> +        cs = vcpu >= 0 ? qemu_get_cpu(vcpu) : monitor_hmp_get_cpu(hmp);
>  
>          if (!cs) {
>              if (vcpu >= 0) {
> @@ -602,13 +600,14 @@ void hmp_info_registers(MonitorHMP *hmp, const QDict *qdict)
>      }
>  }
>  
> -static void memory_dump(Monitor *mon, int count, int format, int wsize,
> +static void memory_dump(MonitorHMP *hmp, int count, int format, int wsize,
>                          uint64_t addr, bool is_physical)
>  {
> +    Monitor *mon = MONITOR(hmp);
>      int l, line_size, i, max_digits, len;
>      uint8_t buf[16];
>      uint64_t v;
> -    CPUState *cs = mon_get_cpu(mon);
> +    CPUState *cs = monitor_hmp_get_cpu(hmp);
>      const unsigned int addr_width = is_physical ? 8 : (target_long_bits() / 4);
>      const bool big_endian = target_big_endian();
>  
> @@ -712,24 +711,22 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
>  
>  void hmp_memory_dump(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      int count = qdict_get_int(qdict, "count");
>      int format = qdict_get_int(qdict, "format");
>      int size = qdict_get_int(qdict, "size");
>      vaddr addr = qdict_get_int(qdict, "addr");
>  
> -    memory_dump(mon, count, format, size, addr, false);
> +    memory_dump(hmp, count, format, size, addr, false);
>  }
>  
>  void hmp_physical_memory_dump(MonitorHMP *hmp, const QDict *qdict)
>  {
> -    Monitor *mon = MONITOR(hmp);
>      int count = qdict_get_int(qdict, "count");
>      int format = qdict_get_int(qdict, "format");
>      int size = qdict_get_int(qdict, "size");
>      hwaddr addr = qdict_get_int(qdict, "addr");
>  
> -    memory_dump(mon, count, format, size, addr, true);
> +    memory_dump(hmp, count, format, size, addr, true);
>  }
>  
>  void hmp_gpa2hva(MonitorHMP *hmp, const QDict *qdict)
> @@ -757,7 +754,7 @@ void hmp_gva2gpa(MonitorHMP *hmp, const QDict *qdict)
>  {
>      Monitor *mon = MONITOR(hmp);
>      vaddr addr = qdict_get_int(qdict, "addr");
> -    CPUState *cs = mon_get_cpu(mon);
> +    CPUState *cs = monitor_hmp_get_cpu(hmp);
>      TranslateForDebugResult tres;
>  
>      if (!cs) {
> diff --git a/monitor/hmp.c b/monitor/hmp.c
> index 47fb7cef6de2..2484a2310dff 100644
> --- a/monitor/hmp.c
> +++ b/monitor/hmp.c
> @@ -411,10 +411,10 @@ void hmp_help_cmd(Monitor *mon, const char *name)
>   * Set @pval to the value in the register identified by @name.
>   * return %true if the register is found, %false otherwise.
>   */
> -static bool gdb_get_register(Monitor *mon, int64_t *pval, const char *name)
> +static bool gdb_get_register(MonitorHMP *hmp, int64_t *pval, const char *name)
>  {
>      g_autoptr(GArray) regs = NULL;
> -    CPUState *cs = mon_get_cpu(mon);
> +    CPUState *cs = monitor_hmp_get_cpu(hmp);
>  
>      if (cs == NULL) {
>          return false;
> @@ -452,7 +452,7 @@ static bool gdb_get_register(Monitor *mon, int64_t *pval, const char *name)
>  static const char *pch;
>  static sigjmp_buf expr_env;
>  
> -static int get_monitor_def(Monitor *mon, int64_t *pval, const char *name);
> +static int get_monitor_def(MonitorHMP *mon, int64_t *pval, const char *name);
>  
>  static G_NORETURN G_GNUC_PRINTF(2, 3)
>  void expr_error(Monitor *mon, const char *fmt, ...)
> @@ -535,8 +535,8 @@ static int64_t expr_unary(Monitor *mon)
>                  pch++;
>              }
>              *q = 0;
> -            if (!gdb_get_register(mon, &reg, buf)
> -                && get_monitor_def(mon, &reg, buf) < 0) {
> +            if (!gdb_get_register(MONITOR_HMP(mon), &reg, buf)
> +                && get_monitor_def(MONITOR_HMP(mon), &reg, buf) < 0) {
>                  expr_error(mon, "unknown register");
>              }
>              n = reg;
> @@ -1733,9 +1733,9 @@ void monitor_register_hmp_info_hrt(const char *name,
>   * Set @pval to the value in the register identified by @name.
>   * return 0 if OK, -1 if not found
>   */
> -static int get_monitor_def(Monitor *mon, int64_t *pval, const char *name)
> +static int get_monitor_def(MonitorHMP *hmp, int64_t *pval, const char *name)
>  {
> -    CPUState *cs = mon_get_cpu(mon);
> +    CPUState *cs = monitor_hmp_get_cpu(hmp);
>      const MonitorDef *md;
>      void *ptr;
>  
> @@ -1750,9 +1750,9 @@ static int get_monitor_def(Monitor *mon, int64_t *pval, const char *name)
>      for (; md->name != NULL; md++) {
>          if (hmp_compare_cmd(name, md->name)) {
>              if (md->get_value) {
> -                *pval = md->get_value(mon, md, md->offset);
> +                *pval = md->get_value(hmp, md, md->offset);
>              } else {
> -                CPUArchState *env = mon_get_cpu_env(mon);
> +                CPUArchState *env = monitor_hmp_get_cpu_env(hmp);
>                  ptr = (uint8_t *)env + md->offset;
>                  *pval = *(int32_t *)ptr;
>              }
> diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
> index a0fa37c887ed..afdda1386080 100644
> --- a/monitor/monitor-internal.h
> +++ b/monitor/monitor-internal.h
> @@ -215,7 +215,7 @@ int monitor_can_read(void *opaque);
>  void monitor_cancel_out_watch(Monitor *mon);
>  void monitor_list_append(Monitor *mon);
>  void monitor_fdsets_cleanup(void);
> -int monitor_set_cpu(Monitor *mon, int cpu_index);
> +int monitor_hmp_set_cpu(MonitorHMP *mon, int cpu_index);
>  
>  void qmp_send_response(MonitorQMP *mon, const QDict *rsp);
>  void monitor_data_destroy_qmp(MonitorQMP *mon);
> diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
> index 6cb0b587fbd4..b16119f4858c 100644
> --- a/monitor/qmp-cmds.c
> +++ b/monitor/qmp-cmds.c
> @@ -169,7 +169,7 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
>      MonitorHMP *hmp = MONITOR_HMP(object_new(TYPE_MONITOR_HMP));
>  
>      if (has_cpu_index) {
> -        int ret = monitor_set_cpu(&hmp->parent_obj, cpu_index);
> +        int ret = monitor_hmp_set_cpu(hmp, cpu_index);
>          if (ret < 0) {
>              error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",
>                         "a CPU number");
> diff --git a/stats/stats-hmp-cmds.c b/stats/stats-hmp-cmds.c
> index f280ad8c4314..cd1f1deb58bc 100644
> --- a/stats/stats-hmp-cmds.c
> +++ b/stats/stats-hmp-cmds.c
> @@ -226,7 +226,7 @@ void hmp_info_stats(MonitorHMP *hmp, const QDict *qdict)
>          filter = stats_filter(target, names, -1, provider);
>          break;
>      case STATS_TARGET_VCPU: {}
> -        int cpu_index = monitor_get_cpu_index(mon);
> +        int cpu_index = monitor_hmp_get_cpu_index(hmp);
>          filter = stats_filter(target, names, cpu_index, provider);
>          break;
>      case STATS_TARGET_CRYPTODEV:
> diff --git a/target/i386/cpu-apic.c b/target/i386/cpu-apic.c
> index 2cb3147837d1..3ae20f004b64 100644
> --- a/target/i386/cpu-apic.c
> +++ b/target/i386/cpu-apic.c
> @@ -93,7 +93,7 @@ void hmp_info_local_apic(MonitorHMP *hmp, const QDict *qdict)
>              cpu_synchronize_state(cs);
>          }
>      } else {
> -        cs = mon_get_cpu(mon);
> +        cs = monitor_hmp_get_cpu(hmp);
>      }
>  
>  
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index e5ffb10d1565..f0687b5c482d 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -10853,10 +10853,10 @@ static const Property x86_cpu_properties[] = {
>  
>  #ifndef CONFIG_USER_ONLY
>  
> -static int64_t monitor_get_pc(Monitor *mon, const struct MonitorDef *md,
> +static int64_t monitor_get_pc(MonitorHMP *hmp, const struct MonitorDef *md,
>                                int offset)
>  {
> -    CPUArchState *env = mon_get_cpu_env(mon);
> +    CPUArchState *env = monitor_hmp_get_cpu_env(hmp);
>      int64_t ret = env->eip + env->segs[R_CS].base;
>  
>      if (!(env->hflags & HF_CS64_MASK)) {
> diff --git a/target/i386/monitor.c b/target/i386/monitor.c
> index f68dd38ac225..72bcab131f77 100644
> --- a/target/i386/monitor.c
> +++ b/target/i386/monitor.c
> @@ -215,7 +215,7 @@ void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
>      CPUArchState *env;
>      AddressSpace *as;
>  
> -    env = mon_get_cpu_env(mon);
> +    env = monitor_hmp_get_cpu_env(hmp);
>      if (!env) {
>          monitor_printf(mon, "No CPU available\n");
>          return;
> @@ -542,7 +542,7 @@ void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
>      CPUArchState *env;
>      AddressSpace *as;
>  
> -    env = mon_get_cpu_env(mon);
> +    env = monitor_hmp_get_cpu_env(hmp);
>      if (!env) {
>          monitor_printf(mon, "No CPU available\n");
>          return;
> diff --git a/target/m68k/monitor.c b/target/m68k/monitor.c
> index 0414474f2ffb..5645a5d4d4f5 100644
> --- a/target/m68k/monitor.c
> +++ b/target/m68k/monitor.c
> @@ -13,7 +13,7 @@
>  void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
>  {
>      Monitor *mon = MONITOR(hmp);
> -    CPUArchState *env1 = mon_get_cpu_env(mon);
> +    CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
>  
>      if (!env1) {
>          monitor_printf(mon, "No CPU available\n");
> diff --git a/target/ppc/monitor.c b/target/ppc/monitor.c
> index 99eda7351877..5769829bdd7e 100644
> --- a/target/ppc/monitor.c
> +++ b/target/ppc/monitor.c
> @@ -14,7 +14,7 @@
>  void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
>  {
>      Monitor *mon = MONITOR(hmp);
> -    CPUArchState *env1 = mon_get_cpu_env(mon);
> +    CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
>  
>      if (!env1) {
>          monitor_printf(mon, "No CPU available\n");
> diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
> index 496d519c978d..4c9c0c793b36 100644
> --- a/target/riscv/monitor.c
> +++ b/target/riscv/monitor.c
> @@ -220,7 +220,7 @@ void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
>      Monitor *mon = MONITOR(hmp);
>      CPUArchState *env;
>  
> -    env = mon_get_cpu_env(mon);
> +    env = monitor_hmp_get_cpu_env(hmp);
>      if (!env) {
>          monitor_printf(mon, "No CPU available\n");
>          return;
> diff --git a/target/sh4/monitor.c b/target/sh4/monitor.c
> index 50da650b2e04..4e443152bf56 100644
> --- a/target/sh4/monitor.c
> +++ b/target/sh4/monitor.c
> @@ -41,7 +41,7 @@ static void print_tlb(Monitor *mon, int idx, tlb_t *tlb)
>  void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
>  {
>      Monitor *mon = MONITOR(hmp);
> -    CPUArchState *env = mon_get_cpu_env(mon);
> +    CPUArchState *env = monitor_hmp_get_cpu_env(hmp);
>      int i;
>  
>      if (!env) {
> diff --git a/target/sparc/monitor.c b/target/sparc/monitor.c
> index 09a15b821a1a..e826e584a918 100644
> --- a/target/sparc/monitor.c
> +++ b/target/sparc/monitor.c
> @@ -30,7 +30,7 @@
>  void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
>  {
>      Monitor *mon = MONITOR(hmp);
> -    CPUArchState *env1 = mon_get_cpu_env(mon);
> +    CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
>  
>      if (!env1) {
>          monitor_printf(mon, "No CPU available\n");
> diff --git a/target/xtensa/monitor.c b/target/xtensa/monitor.c
> index a1082c44e11c..b7b7387706f3 100644
> --- a/target/xtensa/monitor.c
> +++ b/target/xtensa/monitor.c
> @@ -29,7 +29,7 @@
>  void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
>  {
>      Monitor *mon = MONITOR(hmp);
> -    CPUArchState *env1 = mon_get_cpu_env(mon);
> +    CPUArchState *env1 = monitor_hmp_get_cpu_env(hmp);
>  
>      if (!env1) {
>          monitor_printf(mon, "No CPU available\n");
> 
> -- 
> 2.55.0.543.g5ebe2ebe4ea8
> 
-- 
 -----Open up your eyes, open up your mind, open up your code -------   
/ Dr. David Alan Gilbert    |       Running GNU/Linux       | Happy  \ 
\        dave @ treblig.org |                               | In Hex /
 \ _________________________|_____ http://www.treblig.org   |_______/


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

end of thread, other threads:[~2026-08-18 14:16 UTC | newest]

Thread overview: 73+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-16 19:12 [PATCH v3 00/49] Make HMP optional (and later standalone) Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 01/49] vl: fix -monitor none prefix matching Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 02/49] hmp: remove 'vcpu' argument from trace-event help Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 03/49] hmp: fix snapshot_blkdev argument type Marc-André Lureau
2026-08-17  3:51   ` Philippe Mathieu-Daudé
2026-08-16 19:12 ` [PATCH v3 04/49] target/i386: decouple cpu_x86_inject_mce() from Monitor Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 05/49] target/i386: return an error for invalid CPU in hmp_mce() Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 06/49] system: move gpa2hva() to system memory unit Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 07/49] system: decouple qmp_inject_nmi() from Monitor Marc-André Lureau
2026-08-17  3:53   ` Philippe Mathieu-Daudé
2026-08-17  8:04     ` Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 08/49] monitor: move HMP-only fields from Monitor to MonitorHMP Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 09/49] tests/functional: use query-version QMP command instead of HMP Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 10/49] net/qapi: add x-query-usernet command Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 11/49] python, tests: switch usernet queries from HMP to QMP Marc-André Lureau
2026-08-17  7:30   ` Thomas Huth
2026-08-17  8:07     ` Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 12/49] tests/qtest/pnv: drop unnecessary -serial mon:stdio Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 13/49] tests/qtest/qmp-test: don't depend on human-monitor-command Marc-André Lureau
2026-08-17  3:55   ` Philippe Mathieu-Daudé
2026-08-17  8:11     ` Marc-André Lureau
2026-08-17  9:11       ` Philippe Mathieu-Daudé
2026-08-16 19:12 ` [PATCH v3 14/49] tests/qtest/numa-test: replace HMP "info numa" with QMP query-cpus-fast Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 15/49] tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block Marc-André Lureau
2026-08-16 19:53   ` Denis V. Lunev
2026-08-16 19:12 ` [PATCH v3 16/49] tests/qtest/device-introspect-test: fix test without HMP Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 17/49] tests/qemu-iotests/205: fix race in assertExportNotFound Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 18/49] net: add x-query-network QMP command Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 19/49] tests/qtest/netdev-socket: replace HMP with x-query-network QMP Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 20/49] qemu-io: propagate errors through Error API instead of printf Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 21/49] block: add x-qemu-io QMP command Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 22/49] qtest: add qemu-io command to the qtest protocol Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 23/49] qtest/ide-test: convert to use qtest qemu-io command Marc-André Lureau
2026-08-16 19:54   ` Denis V. Lunev
2026-08-16 19:12 ` [PATCH v3 24/49] tests/qemu-iotests: add qmp_qemu_io() Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 25/49] tests/qemu-iotests: convert pause/resume_drive() to QMP Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 26/49] build-sys: add 'hmp' option Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 27/49] monitor: reject readline monitor when HMP is disabled Marc-André Lureau
2026-08-16 20:23   ` Dr. David Alan Gilbert
2026-08-16 19:12 ` [PATCH v3 28/49] system: guard HMP initialization paths with CONFIG_HMP Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 29/49] tests: skip HMP-dependent tests when HMP is disabled Marc-André Lureau
2026-08-16 19:12 ` [PATCH v3 30/49] monitor: isolate HMP declarations in hmp.h Marc-André Lureau
2026-08-16 20:21   ` Dr. David Alan Gilbert
2026-08-16 19:12 ` [PATCH v3 31/49] monitor: change HMPCommand cmd to take MonitorHMP Marc-André Lureau
2026-08-16 21:51   ` Dr. David Alan Gilbert
2026-08-17 18:08     ` Jason J. Herne
2026-08-16 19:12 ` [PATCH v3 32/49] monitor: make hmp_handle_error() " Marc-André Lureau
2026-08-17  0:36   ` Dr. David Alan Gilbert
2026-08-16 19:13 ` [PATCH v3 33/49] monitor: add monitor_cur_hmp() helper Marc-André Lureau
2026-08-17  0:49   ` Dr. David Alan Gilbert
2026-08-16 19:13 ` [PATCH v3 34/49] qemu-print: switch to use monitor_cur_hmp() Marc-André Lureau
2026-08-16 19:13 ` [PATCH v3 35/49] error-report: " Marc-André Lureau
2026-08-16 19:13 ` [PATCH v3 36/49] monitor: tighten monitor_set_cpu()/get_cpu() Marc-André Lureau
2026-08-18 14:15   ` Dr. David Alan Gilbert
2026-08-16 19:13 ` [PATCH v3 37/49] monitor: tighten monitor_printf*() Marc-André Lureau
2026-08-17 18:09   ` Jason J. Herne
2026-08-16 19:13 ` [PATCH v3 38/49] hexagon: make dump_mmu() take MonitorHMP Marc-André Lureau
2026-08-17  3:49   ` Philippe Mathieu-Daudé
2026-08-16 19:13 ` [PATCH v3 39/49] qdev-monitor: make print_dev() callback " Marc-André Lureau
2026-08-17  3:48   ` Philippe Mathieu-Daudé
2026-08-16 19:13 ` [PATCH v3 40/49] qapi: make HMP-specific schema entries conditional on CONFIG_HMP Marc-André Lureau
2026-08-16 19:13 ` [PATCH v3 41/49] Guard HMP command implementations with CONFIG_HMP Marc-André Lureau
2026-08-17 18:11   ` Jason J. Herne
2026-08-16 19:13 ` [PATCH v3 42/49] target: guard MonitorDef tables " Marc-André Lureau
2026-08-17  3:47   ` Philippe Mathieu-Daudé
2026-08-16 19:13 ` [PATCH v3 43/49] hw: guard BusClass::print_dev " Marc-André Lureau
2026-08-16 19:13 ` [PATCH v3 44/49] hexagon: condition HMP-specific code Marc-André Lureau
2026-08-17  3:46   ` Philippe Mathieu-Daudé
2026-08-16 19:13 ` [PATCH v3 45/49] build-sys: make HMP source files conditional on have_hmp Marc-André Lureau
2026-08-16 19:13 ` [PATCH v3 46/49] stubs: split monitor-core stubs into separate compilation units Marc-André Lureau
2026-08-16 19:13 ` [PATCH v3 47/49] monitor: move monitor_hmp_print*() functions to hmp.c Marc-André Lureau
2026-08-16 19:13 ` [PATCH v3 48/49] monitor: move HMP-specific to monitor-hmp-internal.h Marc-André Lureau
2026-08-16 19:13 ` [PATCH v3 49/49] gitlab: --disable-hmp in build-without-defaults Marc-André Lureau

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.