All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers
@ 2026-09-11 12:27 Marc-André Lureau
  2026-09-11 12:27 ` [PATCH 01/10] hmp: don't crash on invalid register Marc-André Lureau
                   ` (11 more replies)
  0 siblings, 12 replies; 25+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau

Hi,

HMP monitor supports printing $register expression. The lookup
was done via GDB stub registers, and supplementary MonitorDef
HMP-specific tables.

Migrate HMP registers to use the GDB infrastructure and remove the
legacy HMP MonitorDef. Use a "qemu-debug" register group, as they are
aliases or synthetic registers, but gdb doesn't seem to care.

Known behavioural changes on RISC-V: CSR lookup is now case-sensitive
and vector registers now report "unkown register" instead of a
target-specific message ("Unable to print the value of vector vreg 'v0'
from this API")

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
Marc-André Lureau (10):
      hmp: don't crash on invalid register
      gdbstub: fix next register base after register gaps
      gdbstub: set feature->base_reg for dynamic features
      target/i386: expose segment limits via GDB
      monitor/hmp: add CPUClass::get_pc fallback for HMP $pc
      target/m68k: expose system registers via GDB
      target/sparc64: expose system registers via GDB
      target/riscv: bypass smstateen check in debugger mode
      target/riscv: expose register aliases via GDB
      monitor/hmp: remove legacy MonitorDef infrastructure

 configs/targets/i386-softmmu.mak          |   2 +-
 configs/targets/m68k-softmmu.mak          |   2 +-
 configs/targets/riscv32-linux-user.mak    |   2 +-
 configs/targets/riscv32-softmmu.mak       |   2 +-
 configs/targets/riscv64-bsd-user.mak      |   2 +-
 configs/targets/riscv64-linux-user.mak    |   2 +-
 configs/targets/riscv64-softmmu.mak       |   2 +-
 configs/targets/sparc64-softmmu.mak       |   2 +-
 configs/targets/x86_64-softmmu.mak        |   2 +-
 gdbstub/gdb-xml/i386-segments.xml         |  14 +++
 gdbstub/gdb-xml/m68k-system.xml           |  32 +++++++
 gdbstub/gdb-xml/riscv-32bit-alias.xml     | 105 ++++++++++++++++++++++
 gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml |  40 +++++++++
 gdbstub/gdb-xml/riscv-64bit-alias.xml     | 105 ++++++++++++++++++++++
 gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml |  46 ++++++++++
 gdbstub/gdb-xml/sparc64-system.xml        |  22 +++++
 gdbstub/gdbstub.c                         |  14 +--
 include/hw/core/cpu.h                     |   2 +-
 include/hw/core/sysemu-cpu-ops.h          |  16 ----
 include/monitor/hmp.h                     |   6 --
 include/qemu/typedefs.h                   |   1 -
 monitor/hmp.c                             |  52 ++---------
 target/arm/gdbstub.c                      |   8 +-
 target/arm/gdbstub64.c                    |  10 ++-
 target/i386/cpu.c                         |  32 -------
 target/i386/gdbstub.c                     |  24 +++++
 target/m68k/cpu.c                         |  22 -----
 target/m68k/helper.c                      |  47 ++++++++++
 target/ppc/gdbstub.c                      |   2 +-
 target/riscv/cpu.c                        |   1 -
 target/riscv/gdbstub.c                    |  52 ++++++++++-
 target/riscv/internals.h                  |   3 -
 target/riscv/monitor.c                    | 140 ------------------------------
 target/riscv/tcg/csr.c                    |   3 +-
 target/sparc/cpu.c                        |  19 ----
 target/sparc/gdbstub.c                    |  38 ++++++++
 target/xtensa/cpu.c                       |   2 +-
 37 files changed, 562 insertions(+), 314 deletions(-)
---
base-commit: 209b2afaface001c7d4d981e38f186afe7b24a50
change-id: 20260910-query-reg-80cd59cf4707

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



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

* [PATCH 01/10] hmp: don't crash on invalid register
  2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
  2026-09-30 16:59   ` Philippe Mathieu-Daudé
  2026-09-11 12:27 ` [PATCH 02/10] gdbstub: fix next register base after register gaps Marc-André Lureau
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 25+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau

When printing an invalid/denied register, QEMU crashes with:
ERROR:include/qemu/bswap.h:488:ldn_le_p: code should not be reached

(ex: "p $sireg" when siselect=0 on riscv)

Return false instead.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 monitor/hmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/monitor/hmp.c b/monitor/hmp.c
index 488ec23937df..10e19e417aba 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -424,7 +424,7 @@ static bool gdb_get_register(MonitorHMP *hmp, int64_t *pval, const char *name)
 
         buf = g_byte_array_new();
         reg_size = gdb_read_register(cs, buf, reg->gdb_reg);
-        if (reg_size > sizeof(*pval)) {
+        if (reg_size == 0 || reg_size > sizeof(*pval)) {
             return false;
         }
 

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH 02/10] gdbstub: fix next register base after register gaps
  2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
  2026-09-11 12:27 ` [PATCH 01/10] hmp: don't crash on invalid register Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
  2026-09-11 15:29   ` Alex Bennée
  2026-09-11 12:27 ` [PATCH 03/10] gdbstub: set feature->base_reg for dynamic features Marc-André Lureau
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 25+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau

Commit b3e88abb200c ("gdbstub: Consider GDBFeature::base_reg in
gdb_register_coprocessor()") identified that register numbers may
have gaps. We also need to adjust the next base_reg correctly
to avoid overlapping registers. Rename the field to be more
explicit about its usage.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 gdbstub/gdbstub.c      | 13 ++++++-------
 include/hw/core/cpu.h  |  2 +-
 target/arm/gdbstub.c   |  8 +++++---
 target/arm/gdbstub64.c | 10 ++++++----
 target/ppc/gdbstub.c   |  2 +-
 target/riscv/gdbstub.c |  9 ++++++---
 target/xtensa/cpu.c    |  2 +-
 7 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 0a328b0dd488..0ce871d74929 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -605,13 +605,13 @@ void gdb_init_cpu(CPUState *cpu)
         gdb_register_feature(cpu, 0,
                              cc->gdb_read_register, cc->gdb_write_register,
                              feature);
-        cpu->gdb_num_regs = cpu->gdb_num_g_regs = feature->num_regs;
+        cpu->gdb_next_base_reg = cpu->gdb_num_g_regs = feature->num_regs;
     } else {
-        cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
+        cpu->gdb_next_base_reg = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
     }
 
     trace_gdbxml_init_cpu(object_get_typename(OBJECT(cpu)), cpu->cpu_index,
-                          cpu->gdb_num_regs, cpu->gdb_num_g_regs,
+                          cpu->gdb_next_base_reg, cpu->gdb_num_g_regs,
                           cc->gdb_num_core_regs);
 }
 
@@ -621,7 +621,7 @@ void gdb_register_coprocessor(CPUState *cpu,
 {
     GDBRegisterState *s;
     guint i;
-    int base_reg = cpu->gdb_num_regs;
+    int base_reg = cpu->gdb_next_base_reg;
 
     for (i = 0; i < cpu->gdb_regs->len; i++) {
         /* Check for duplicates.  */
@@ -639,7 +639,7 @@ void gdb_register_coprocessor(CPUState *cpu,
     gdb_register_feature(cpu, base_reg, get_reg, set_reg, feature);
 
     /* Add to end of list.  */
-    cpu->gdb_num_regs += feature->num_regs;
+    cpu->gdb_next_base_reg = base_reg + feature->num_regs;
 }
 
 void gdb_unregister_coprocessor_all(CPUState *cpu)
@@ -651,7 +651,7 @@ void gdb_unregister_coprocessor_all(CPUState *cpu)
     g_array_free(cpu->gdb_regs, true);
 
     cpu->gdb_regs = NULL;
-    cpu->gdb_num_regs = 0;
+    cpu->gdb_next_base_reg = 0;
     cpu->gdb_num_g_regs = 0;
 }
 
@@ -2522,4 +2522,3 @@ void gdb_create_default_process(GDBState *s)
     process->attached = false;
     process->target_xml = NULL;
 }
-
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 328e30045ce1..02212f555c2e 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -521,7 +521,7 @@ struct CPUState {
     struct CPUJumpCache *tb_jmp_cache;
 
     GArray *gdb_regs;
-    int gdb_num_regs;
+    int gdb_next_base_reg;
     int gdb_num_g_regs;
     QTAILQ_ENTRY(CPUState) node;
 
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
index d6e29c4cf467..e5cbe4d951ef 100644
--- a/target/arm/gdbstub.c
+++ b/target/arm/gdbstub.c
@@ -555,19 +555,21 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
         gdb_register_coprocessor(cs, mve_gdb_get_reg, mve_gdb_set_reg,
                                  gdb_find_static_feature("arm-m-profile-mve.xml"));
     }
+    GDBFeature *feature =
+        arm_gen_dynamic_sysreg_feature(cs, cs->gdb_next_base_reg);
     gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
-                             arm_gen_dynamic_sysreg_feature(cs, cs->gdb_num_regs));
+                             feature);
 
 #ifdef CONFIG_TCG
     if (arm_feature(env, ARM_FEATURE_M) && tcg_enabled()) {
         gdb_register_coprocessor(cs,
             arm_gdb_get_m_systemreg, arm_gdb_set_m_systemreg,
-            arm_gen_dynamic_m_systemreg_feature(cs, cs->gdb_num_regs));
+            arm_gen_dynamic_m_systemreg_feature(cs, cs->gdb_next_base_reg));
 #ifndef CONFIG_USER_ONLY
         if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
             gdb_register_coprocessor(cs,
                 arm_gdb_get_m_secextreg, arm_gdb_set_m_secextreg,
-                arm_gen_dynamic_m_secextreg_feature(cs, cs->gdb_num_regs));
+                arm_gen_dynamic_m_secextreg_feature(cs, cs->gdb_next_base_reg));
         }
 #endif
     }
diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
index 0c3e5b30bd6a..cf5b95b54641 100644
--- a/target/arm/gdbstub64.c
+++ b/target/arm/gdbstub64.c
@@ -885,7 +885,8 @@ void aarch64_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
     CPUState *cs = CPU(cpu);
     if (isar_feature_aa64_sve(&cpu->isar) ||
         isar_feature_aa64_sme(&cpu->isar)) {
-        GDBFeature *feature = arm_gen_dynamic_svereg_feature(cs, cs->gdb_num_regs);
+        GDBFeature *feature =
+            arm_gen_dynamic_svereg_feature(cs, cs->gdb_next_base_reg);
         gdb_register_coprocessor(cs, aarch64_gdb_get_sve_reg,
                                  aarch64_gdb_set_sve_reg, feature);
     } else {
@@ -896,7 +897,7 @@ void aarch64_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
 
     if (isar_feature_aa64_sme(&cpu->isar)) {
         GDBFeature *sme_feature =
-            arm_gen_dynamic_smereg_feature(cs, cs->gdb_num_regs);
+            arm_gen_dynamic_smereg_feature(cs, cs->gdb_next_base_reg);
         gdb_register_coprocessor(cs, aarch64_gdb_get_sme_reg,
                                  aarch64_gdb_set_sme_reg, sme_feature);
         if (isar_feature_aa64_sme2(&cpu->isar)) {
@@ -927,7 +928,8 @@ void aarch64_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
 #endif
 
     /* All AArch64 CPUs have at least TPIDR */
+    GDBFeature *tls_feature =
+        arm_gen_dynamic_tls_feature(cs, cs->gdb_next_base_reg);
     gdb_register_coprocessor(cs, aarch64_gdb_get_tls_reg,
-                             aarch64_gdb_set_tls_reg,
-                             arm_gen_dynamic_tls_feature(cs, cs->gdb_num_regs));
+                             aarch64_gdb_set_tls_reg, tls_feature);
 }
diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c
index 4d622c5cad59..ec25c541c685 100644
--- a/target/ppc/gdbstub.c
+++ b/target/ppc/gdbstub.c
@@ -206,7 +206,7 @@ static void gdb_gen_spr_feature(CPUState *cs)
 
     gdb_feature_builder_init(&builder, &pcc->gdb_spr,
                              "org.qemu.power.spr", "power-spr.xml",
-                             cs->gdb_num_regs);
+                             cs->gdb_next_base_reg);
 
     for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
         ppc_spr_t *spr = &env->spr_cb[i];
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 9abbf5bcdf0e..f279f4ab2461 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -348,9 +348,10 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
                                  gdb_find_static_feature("riscv-32bit-fpu.xml"));
     }
     if (cpu->cfg.ext_zve32x) {
+        GDBFeature *feature =
+            ricsv_gen_dynamic_vector_feature(cs, cs->gdb_next_base_reg);
         gdb_register_coprocessor(cs, riscv_gdb_get_vector,
-                                 riscv_gdb_set_vector,
-                                 ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs));
+                                 riscv_gdb_set_vector, feature);
     }
 
 #ifdef CONFIG_TCG
@@ -373,8 +374,10 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
     }
 
     if (cpu->cfg.ext_zicsr) {
+        GDBFeature *feature =
+            riscv_gen_dynamic_csr_feature(cs, cs->gdb_next_base_reg);
         gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
-                                 riscv_gen_dynamic_csr_feature(cs, cs->gdb_num_regs));
+                                 feature);
     }
 #endif
 }
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 7c25b9ab707a..48863a1859d4 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -263,7 +263,7 @@ static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
         return;
     }
 
-    cs->gdb_num_regs = xcc->config->gdb_regmap.num_regs;
+    cs->gdb_next_base_reg = xcc->config->gdb_regmap.num_regs;
 
     qemu_init_vcpu(cs);
 

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH 03/10] gdbstub: set feature->base_reg for dynamic features
  2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
  2026-09-11 12:27 ` [PATCH 01/10] hmp: don't crash on invalid register Marc-André Lureau
  2026-09-11 12:27 ` [PATCH 02/10] gdbstub: fix next register base after register gaps Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
  2026-09-30 17:18   ` Philippe Mathieu-Daudé
  2026-09-11 12:27 ` [PATCH 04/10] target/i386: expose segment limits via GDB Marc-André Lureau
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 25+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau

gdb_feature_builder_end() never propagated builder->base_reg into
feature->base_reg, leaving it at 0 for all dynamically-built features.
This made the trace log at gdb_get_register_list() report an incorrect
base_reg for dynamic features.

GDBRegisterState::base_reg was correctly set, so this doesn't fix
an actual issue.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 gdbstub/gdbstub.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 0ce871d74929..912e31b66744 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -476,6 +476,7 @@ void gdb_feature_builder_end(const GDBFeatureBuilder *builder)
 
     g_ptr_array_free(builder->xml, TRUE);
 
+    builder->feature->base_reg = builder->base_reg;
     builder->feature->num_regs = builder->regs->len;
     builder->feature->regs = (void *)g_ptr_array_free(builder->regs, FALSE);
     trace_gdbxml_feature_builder_header(builder->feature->name,

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH 04/10] target/i386: expose segment limits via GDB
  2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
                   ` (2 preceding siblings ...)
  2026-09-11 12:27 ` [PATCH 03/10] gdbstub: set feature->base_reg for dynamic features Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
  2026-09-11 12:27 ` [PATCH 05/10] monitor/hmp: add CPUClass::get_pc fallback for HMP $pc Marc-André Lureau
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau

Add an i386-segments.xml GDB feature that exposes the six segment
limit registers (cs, ds, es, ss, fs, gs) as read-only system
registers through the GDB coprocessor interface. This makes them
accessible to both GDB and HMP without relying on the legacy
MonitorDef table, which will be removed in a subsequent commit.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 configs/targets/i386-softmmu.mak   |  2 +-
 configs/targets/x86_64-softmmu.mak |  2 +-
 gdbstub/gdb-xml/i386-segments.xml  | 14 ++++++++++++++
 target/i386/gdbstub.c              | 24 ++++++++++++++++++++++++
 4 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/configs/targets/i386-softmmu.mak b/configs/targets/i386-softmmu.mak
index 38a8f85201f9..89cdaa072ef7 100644
--- a/configs/targets/i386-softmmu.mak
+++ b/configs/targets/i386-softmmu.mak
@@ -1,6 +1,6 @@
 TARGET_ARCH=i386
 TARGET_KVM_HAVE_GUEST_DEBUG=y
 TARGET_KVM_HAVE_RESET_PARKED_VCPU=y
-TARGET_XML_FILES= i386-32bit.xml
+TARGET_XML_FILES= i386-32bit.xml i386-segments.xml
 TARGET_LONG_BITS=32
 TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
diff --git a/configs/targets/x86_64-softmmu.mak b/configs/targets/x86_64-softmmu.mak
index c7f8746b4f58..0af699971de0 100644
--- a/configs/targets/x86_64-softmmu.mak
+++ b/configs/targets/x86_64-softmmu.mak
@@ -2,6 +2,6 @@ TARGET_ARCH=x86_64
 TARGET_BASE_ARCH=i386
 TARGET_KVM_HAVE_GUEST_DEBUG=y
 TARGET_KVM_HAVE_RESET_PARKED_VCPU=y
-TARGET_XML_FILES= i386-64bit.xml i386-64bit-apx.xml
+TARGET_XML_FILES= i386-64bit.xml i386-64bit-apx.xml i386-segments.xml
 TARGET_LONG_BITS=64
 TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
diff --git a/gdbstub/gdb-xml/i386-segments.xml b/gdbstub/gdb-xml/i386-segments.xml
new file mode 100644
index 000000000000..6fbf3f91957e
--- /dev/null
+++ b/gdbstub/gdb-xml/i386-segments.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!--
+  SPDX-License-Identifier: GPL-2.0-or-later
+-->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<!-- Segment-cache values are read-only; writes are ignored. -->
+<feature name="org.qemu.gdb.i386.segments">
+  <reg name="cs.limit" bitsize="32" type="uint32" group="qemu-debug" save-restore="no"/>
+  <reg name="ds.limit" bitsize="32" type="uint32" group="qemu-debug" save-restore="no"/>
+  <reg name="es.limit" bitsize="32" type="uint32" group="qemu-debug" save-restore="no"/>
+  <reg name="ss.limit" bitsize="32" type="uint32" group="qemu-debug" save-restore="no"/>
+  <reg name="fs.limit" bitsize="32" type="uint32" group="qemu-debug" save-restore="no"/>
+  <reg name="gs.limit" bitsize="32" type="uint32" group="qemu-debug" save-restore="no"/>
+</feature>
diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index 5c5fa7272163..2729b0f5bc1e 100644
--- a/target/i386/gdbstub.c
+++ b/target/i386/gdbstub.c
@@ -493,6 +493,25 @@ static int i386_cpu_gdb_set_egprs(CPUState *cs, uint8_t *mem_buf, int n)
 }
 #endif
 
+#ifndef CONFIG_USER_ONLY
+static int x86_gdb_read_segment_limit(CPUState *cs, GByteArray *buf, int n)
+{
+    CPUX86State *env = cpu_env(cs);
+    static const int segments[] = { R_CS, R_DS, R_ES, R_SS, R_FS, R_GS };
+
+    if (n < 0 || n >= ARRAY_SIZE(segments)) {
+        return 0;
+    }
+    return gdb_get_reg32(buf, env->segs[segments[n]].limit);
+}
+
+static int x86_gdb_write_segment_limit(CPUState *cs, uint8_t *buf, int n)
+{
+    /* Segment caches are exposed for inspection only. Ignore writes. */
+    return 4;
+}
+#endif
+
 void x86_cpu_gdb_init(CPUState *cs)
 {
 #ifdef TARGET_X86_64
@@ -514,4 +533,9 @@ void x86_cpu_gdb_init(CPUState *cs)
                              gdb_find_static_feature("i386-32bit-linux.xml"));
 #endif
 #endif
+#ifndef CONFIG_USER_ONLY
+    gdb_register_coprocessor(cs, x86_gdb_read_segment_limit,
+                             x86_gdb_write_segment_limit,
+                             gdb_find_static_feature("i386-segments.xml"));
+#endif
 }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH 05/10] monitor/hmp: add CPUClass::get_pc fallback for HMP $pc
  2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
                   ` (3 preceding siblings ...)
  2026-09-11 12:27 ` [PATCH 04/10] target/i386: expose segment limits via GDB Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
  2026-09-30 17:31   ` Philippe Mathieu-Daudé
  2026-09-11 12:27 ` [PATCH 06/10] target/m68k: expose system registers via GDB Marc-André Lureau
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 25+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau

Some targets, including x86, have no GDB register named "pc" (x86
uses eip/rip). When the GDB register lookup fails for "$pc" in
HMP expressions, fall back to CPUClass::get_pc so that "p $pc",
"x $pc" etc. work without relying on the legacy MonitorDef table.

This prepares for the eventual removal of MonitorDef while making
$pc available immediately for all targets that implement get_pc.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 monitor/hmp.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/monitor/hmp.c b/monitor/hmp.c
index 10e19e417aba..0a74247ca66a 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -402,7 +402,7 @@ void hmp_help_cmd(MonitorHMP *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(MonitorHMP *hmp, int64_t *pval, const char *name)
+static bool get_register(MonitorHMP *hmp, int64_t *pval, const char *name)
 {
     g_autoptr(GArray) regs = NULL;
     CPUState *cs = monitor_hmp_get_cpu(hmp);
@@ -435,6 +435,10 @@ static bool gdb_get_register(MonitorHMP *hmp, int64_t *pval, const char *name)
         }
         return true;
     }
+    if (!strcmp(name, "pc") && cs->cc->get_pc) {
+        *pval = cs->cc->get_pc(cs);
+        return true;
+    }
     return false;
 }
 
@@ -526,7 +530,7 @@ static int64_t expr_unary(MonitorHMP *mon)
                 pch++;
             }
             *q = 0;
-            if (!gdb_get_register(mon, &reg, buf)
+            if (!get_register(mon, &reg, buf)
                 && get_monitor_def(mon, &reg, buf) < 0) {
                 expr_error(mon, "unknown register");
             }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH 06/10] target/m68k: expose system registers via GDB
  2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
                   ` (4 preceding siblings ...)
  2026-09-11 12:27 ` [PATCH 05/10] monitor/hmp: add CPUClass::get_pc fallback for HMP $pc Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
  2026-09-11 12:27 ` [PATCH 07/10] target/sparc64: " Marc-André Lureau
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau

Add an m68k-system.xml GDB feature that exposes supervisor stack
pointers (ssp, usp, isp), function code registers (sfc, dfc), MMU
registers (urp, srp, dttr0/1, ittr0/1, mmusr) as read-only system
registers through the GDB coprocessor interface.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 configs/targets/m68k-softmmu.mak |  2 +-
 gdbstub/gdb-xml/m68k-system.xml  | 32 +++++++++++++++++++++++++++
 target/m68k/helper.c             | 47 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/configs/targets/m68k-softmmu.mak b/configs/targets/m68k-softmmu.mak
index 0bc889f326e3..f3ac9b74c862 100644
--- a/configs/targets/m68k-softmmu.mak
+++ b/configs/targets/m68k-softmmu.mak
@@ -1,4 +1,4 @@
 TARGET_ARCH=m68k
 TARGET_BIG_ENDIAN=y
-TARGET_XML_FILES= cf-core.xml cf-fp.xml m68k-core.xml m68k-fp.xml
+TARGET_XML_FILES= cf-core.xml cf-fp.xml m68k-core.xml m68k-fp.xml m68k-system.xml
 TARGET_LONG_BITS=32
diff --git a/gdbstub/gdb-xml/m68k-system.xml b/gdbstub/gdb-xml/m68k-system.xml
new file mode 100644
index 000000000000..0a91be0edc00
--- /dev/null
+++ b/gdbstub/gdb-xml/m68k-system.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+  SPDX-License-Identifier: GPL-2.0-or-later
+-->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<!-- System-register values are read-only; writes are ignored. -->
+<feature name="org.qemu.gdb.m68k.system">
+  <reg name="ssp" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="usp" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="isp" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="sfc" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="dfc" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="urp" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="srp" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="dttr0" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="dttr1" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="ittr0" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="ittr1" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="mmusr" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+</feature>
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index 5f91d206f596..f2615d5bcfb8 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -123,6 +123,48 @@ static int m68k_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
     return 0;
 }
 
+#ifndef CONFIG_USER_ONLY
+static int m68k_gdb_read_system_register(CPUState *cs, GByteArray *buf, int n)
+{
+    CPUM68KState *env = cpu_env(cs);
+    static const int stacks[] = { M68K_SSP, M68K_USP, M68K_ISP };
+
+    if (n >= 0 && n < ARRAY_SIZE(stacks)) {
+        int sp = stacks[n];
+
+        return gdb_get_reg32(buf, env->sp[sp]);
+    }
+    switch (n) {
+    case 3:
+        return gdb_get_reg32(buf, env->sfc);
+    case 4:
+        return gdb_get_reg32(buf, env->dfc);
+    case 5:
+        return gdb_get_reg32(buf, env->mmu.urp);
+    case 6:
+        return gdb_get_reg32(buf, env->mmu.srp);
+    case 7:
+        return gdb_get_reg32(buf, env->mmu.ttr[M68K_DTTR0]);
+    case 8:
+        return gdb_get_reg32(buf, env->mmu.ttr[M68K_DTTR1]);
+    case 9:
+        return gdb_get_reg32(buf, env->mmu.ttr[M68K_ITTR0]);
+    case 10:
+        return gdb_get_reg32(buf, env->mmu.ttr[M68K_ITTR1]);
+    case 11:
+        return gdb_get_reg32(buf, env->mmu.mmusr);
+    default:
+        return 0;
+    }
+}
+
+static int m68k_gdb_write_system_register(CPUState *cs, uint8_t *buf, int n)
+{
+    /* These registers are exposed for inspection only. Ignore writes. */
+    return 4;
+}
+#endif
+
 void m68k_cpu_init_gdb(M68kCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
@@ -135,6 +177,11 @@ void m68k_cpu_init_gdb(M68kCPU *cpu)
         gdb_register_coprocessor(cs, m68k_fpu_gdb_get_reg, m68k_fpu_gdb_set_reg,
                                  gdb_find_static_feature("m68k-fp.xml"));
     }
+#ifndef CONFIG_USER_ONLY
+    gdb_register_coprocessor(cs, m68k_gdb_read_system_register,
+                             m68k_gdb_write_system_register,
+                             gdb_find_static_feature("m68k-system.xml"));
+#endif
     /* TODO: Add [E]MAC registers.  */
 }
 

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH 07/10] target/sparc64: expose system registers via GDB
  2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
                   ` (5 preceding siblings ...)
  2026-09-11 12:27 ` [PATCH 06/10] target/m68k: expose system registers via GDB Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
  2026-09-11 12:27 ` [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode Marc-André Lureau
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau

Add a sparc64-system.xml GDB feature that exposes asi, pstate,
cansave, canrestore, otherwin, wstate, and cleanwin as read-only
system registers through the GDB coprocessor interface.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 configs/targets/sparc64-softmmu.mak |  2 +-
 gdbstub/gdb-xml/sparc64-system.xml  | 22 +++++++++++++++++++++
 target/sparc/gdbstub.c              | 38 +++++++++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/configs/targets/sparc64-softmmu.mak b/configs/targets/sparc64-softmmu.mak
index 4e621fb8e39e..7f2789136653 100644
--- a/configs/targets/sparc64-softmmu.mak
+++ b/configs/targets/sparc64-softmmu.mak
@@ -1,7 +1,7 @@
 TARGET_ARCH=sparc64
 TARGET_BASE_ARCH=sparc
 TARGET_BIG_ENDIAN=y
-TARGET_XML_FILES=sparc64-cpu.xml sparc64-fpu.xml sparc64-cp0.xml
+TARGET_XML_FILES=sparc64-cpu.xml sparc64-fpu.xml sparc64-cp0.xml sparc64-system.xml
 TARGET_LONG_BITS=64
 TARGET_NOT_USING_LEGACY_LDST_PHYS_API=y
 TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
diff --git a/gdbstub/gdb-xml/sparc64-system.xml b/gdbstub/gdb-xml/sparc64-system.xml
new file mode 100644
index 000000000000..e00baedb467e
--- /dev/null
+++ b/gdbstub/gdb-xml/sparc64-system.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+  SPDX-License-Identifier: GPL-2.0-or-later
+-->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<!-- System-register values are read-only; writes are ignored. -->
+<feature name="org.qemu.gdb.sparc.system">
+  <reg name="asi" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="pstate" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="cansave" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="canrestore" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="otherwin" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="wstate" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+  <reg name="cleanwin" bitsize="32" type="uint32"
+       group="qemu-debug" save-restore="no"/>
+</feature>
diff --git a/target/sparc/gdbstub.c b/target/sparc/gdbstub.c
index 2874ce1b3501..ca23a4a94532 100644
--- a/target/sparc/gdbstub.c
+++ b/target/sparc/gdbstub.c
@@ -266,6 +266,39 @@ static int sparc_cp0_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 #endif
 }
 
+#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
+static int sparc64_gdb_read_system_register(CPUState *cs, GByteArray *buf,
+                                           int n)
+{
+    CPUSPARCState *env = cpu_env(cs);
+
+    switch (n) {
+    case 0:
+        return gdb_get_reg32(buf, env->asi);
+    case 1:
+        return gdb_get_reg32(buf, env->pstate);
+    case 2:
+        return gdb_get_reg32(buf, env->cansave);
+    case 3:
+        return gdb_get_reg32(buf, env->canrestore);
+    case 4:
+        return gdb_get_reg32(buf, env->otherwin);
+    case 5:
+        return gdb_get_reg32(buf, env->wstate);
+    case 6:
+        return gdb_get_reg32(buf, env->cleanwin);
+    default:
+        return 0;
+    }
+}
+
+static int sparc64_gdb_write_system_register(CPUState *cs, uint8_t *buf, int n)
+{
+    /* These registers are exposed for inspection only. Ignore writes. */
+    return 4;
+}
+#endif
+
 void sparc_cpu_register_gdb_regs(CPUState *cs)
 {
 #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
@@ -282,5 +315,10 @@ void sparc_cpu_register_gdb_regs(CPUState *cs)
     gdb_register_coprocessor(cs, sparc_cp0_gdb_read_register,
                              sparc_cp0_gdb_write_register,
                              gdb_find_static_feature("sparc64-cp0.xml"));
+#ifndef CONFIG_USER_ONLY
+    gdb_register_coprocessor(cs, sparc64_gdb_read_system_register,
+                             sparc64_gdb_write_system_register,
+                             gdb_find_static_feature("sparc64-system.xml"));
+#endif
 #endif
 }

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode
  2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
                   ` (6 preceding siblings ...)
  2026-09-11 12:27 ` [PATCH 07/10] target/sparc64: " Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
  2026-09-30 18:24   ` Daniel Henrique Barboza
  2026-09-11 12:27 ` [PATCH 09/10] target/riscv: expose register aliases via GDB Marc-André Lureau
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 25+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau

Allow to read CSRs gated by Smstateen extension when env->debugger.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 target/riscv/tcg/csr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c
index bd4b6dc114bc..93a7f419f29f 100644
--- a/target/riscv/tcg/csr.c
+++ b/target/riscv/tcg/csr.c
@@ -53,7 +53,8 @@ RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
 {
     bool virt = env->virt_enabled;
 
-    if (env->priv == PRV_M || !riscv_cpu_cfg(env)->ext_smstateen) {
+    if (env->debugger || env->priv == PRV_M ||
+        !riscv_cpu_cfg(env)->ext_smstateen) {
         return RISCV_EXCP_NONE;
     }
 

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH 09/10] target/riscv: expose register aliases via GDB
  2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
                   ` (7 preceding siblings ...)
  2026-09-11 12:27 ` [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
  2026-09-11 12:27 ` [PATCH 10/10] monitor/hmp: remove legacy MonitorDef infrastructure Marc-André Lureau
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau

The core GDB XML uses ABI names (zero, ra, sp, fp, ft0, fs0, etc.)
but users also refer to registers by their numeric names (x0-x31,
f0-f31) and the s0 alias for fp. The legacy MonitorDef mechanism
supported both via split "x0/zero" name matching.

Register a feature that maps:
 - x0-x31 and s0 to the corresponding core integer registers
 - x0h-x31h and their ABI aliases (zeroh, rah, ...) to env->gprh[]
 - f0-f31 to the corresponding FPU registers (when FPU is present)

This preserves full HMP $register compatibility after the MonitorDef
removal.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 configs/targets/riscv32-linux-user.mak    |   2 +-
 configs/targets/riscv32-softmmu.mak       |   2 +-
 configs/targets/riscv64-bsd-user.mak      |   2 +-
 configs/targets/riscv64-linux-user.mak    |   2 +-
 configs/targets/riscv64-softmmu.mak       |   2 +-
 gdbstub/gdb-xml/riscv-32bit-alias.xml     | 105 ++++++++++++++++++++++++++++++
 gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml |  40 ++++++++++++
 gdbstub/gdb-xml/riscv-64bit-alias.xml     | 105 ++++++++++++++++++++++++++++++
 gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml |  46 +++++++++++++
 target/riscv/gdbstub.c                    |  43 ++++++++++++
 10 files changed, 344 insertions(+), 5 deletions(-)

diff --git a/configs/targets/riscv32-linux-user.mak b/configs/targets/riscv32-linux-user.mak
index d88fdf5e1b2f..8ee14fa14383 100644
--- a/configs/targets/riscv32-linux-user.mak
+++ b/configs/targets/riscv32-linux-user.mak
@@ -1,7 +1,7 @@
 TARGET_ARCH=riscv32
 TARGET_BASE_ARCH=riscv
 TARGET_ABI_DIR=riscv
-TARGET_XML_FILES= riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-32bit-virtual.xml
+TARGET_XML_FILES= riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-32bit-virtual.xml riscv-32bit-alias.xml riscv-32bit-fpu-alias.xml riscv-64bit-fpu-alias.xml
 CONFIG_SEMIHOSTING=y
 CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
 TARGET_SYSTBL_ABI=32
diff --git a/configs/targets/riscv32-softmmu.mak b/configs/targets/riscv32-softmmu.mak
index 5d5016d00832..c717940344f0 100644
--- a/configs/targets/riscv32-softmmu.mak
+++ b/configs/targets/riscv32-softmmu.mak
@@ -1,6 +1,6 @@
 TARGET_ARCH=riscv32
 TARGET_BASE_ARCH=riscv
-TARGET_XML_FILES= riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-32bit-virtual.xml
+TARGET_XML_FILES= riscv-32bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-32bit-virtual.xml riscv-32bit-alias.xml riscv-32bit-fpu-alias.xml riscv-64bit-fpu-alias.xml
 # needed by boot.c
 TARGET_NEED_FDT=y
 TARGET_LONG_BITS=32
diff --git a/configs/targets/riscv64-bsd-user.mak b/configs/targets/riscv64-bsd-user.mak
index 5b4e138099fc..1d37e018c871 100644
--- a/configs/targets/riscv64-bsd-user.mak
+++ b/configs/targets/riscv64-bsd-user.mak
@@ -1,6 +1,6 @@
 TARGET_ARCH=riscv64
 TARGET_BASE_ARCH=riscv
 TARGET_ABI_DIR=riscv
-TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml
+TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml riscv-64bit-alias.xml riscv-32bit-fpu-alias.xml riscv-64bit-fpu-alias.xml
 TARGET_LONG_BITS=64
 TARGET_NOT_USING_LEGACY_NATIVE_ENDIAN_API=y
diff --git a/configs/targets/riscv64-linux-user.mak b/configs/targets/riscv64-linux-user.mak
index 35621520c560..564d15aaca8c 100644
--- a/configs/targets/riscv64-linux-user.mak
+++ b/configs/targets/riscv64-linux-user.mak
@@ -1,7 +1,7 @@
 TARGET_ARCH=riscv64
 TARGET_BASE_ARCH=riscv
 TARGET_ABI_DIR=riscv
-TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml
+TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml riscv-64bit-alias.xml riscv-32bit-fpu-alias.xml riscv-64bit-fpu-alias.xml
 CONFIG_SEMIHOSTING=y
 CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
 TARGET_SYSTBL_ABI=64
diff --git a/configs/targets/riscv64-softmmu.mak b/configs/targets/riscv64-softmmu.mak
index a10dc03c04c8..28bfcdc575fb 100644
--- a/configs/targets/riscv64-softmmu.mak
+++ b/configs/targets/riscv64-softmmu.mak
@@ -1,7 +1,7 @@
 TARGET_ARCH=riscv64
 TARGET_BASE_ARCH=riscv
 TARGET_KVM_HAVE_GUEST_DEBUG=y
-TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml riscv-32bit-cpu.xml riscv-32bit-virtual.xml
+TARGET_XML_FILES= riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml riscv-64bit-virtual.xml riscv-32bit-cpu.xml riscv-32bit-virtual.xml riscv-32bit-alias.xml riscv-64bit-alias.xml riscv-32bit-fpu-alias.xml riscv-64bit-fpu-alias.xml
 # needed by boot.c
 TARGET_NEED_FDT=y
 TARGET_LONG_BITS=64
diff --git a/gdbstub/gdb-xml/riscv-32bit-alias.xml b/gdbstub/gdb-xml/riscv-32bit-alias.xml
new file mode 100644
index 000000000000..a00a86ebdf95
--- /dev/null
+++ b/gdbstub/gdb-xml/riscv-32bit-alias.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<!--
+  SPDX-License-Identifier: GPL-2.0-or-later
+-->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.qemu.gdb.riscv.alias">
+  <reg name="x0" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x1" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x2" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x3" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x4" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x5" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x6" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x7" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x8" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x9" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x10" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x11" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x12" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x13" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x14" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x15" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x16" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x17" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x18" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x19" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x20" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x21" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x22" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x23" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x24" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x25" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x26" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x27" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x28" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x29" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x30" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x31" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s0" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x0h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="zeroh" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x1h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="rah" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x2h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="sph" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x3h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="gph" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x4h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="tph" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x5h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="t0h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x6h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="t1h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x7h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="t2h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x8h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s0h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x9h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s1h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x10h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="a0h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x11h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="a1h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x12h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="a2h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x13h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="a3h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x14h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="a4h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x15h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="a5h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x16h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="a6h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x17h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="a7h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x18h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s2h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x19h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s3h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x20h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s4h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x21h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s5h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x22h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s6h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x23h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s7h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x24h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s8h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x25h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s9h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x26h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s10h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x27h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="s11h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x28h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="t3h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x29h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="t4h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x30h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="t5h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="x31h" bitsize="32" type="int" group="qemu-debug"/>
+  <reg name="t6h" bitsize="32" type="int" group="qemu-debug"/>
+</feature>
diff --git a/gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml b/gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml
new file mode 100644
index 000000000000..3935f72ea289
--- /dev/null
+++ b/gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+  SPDX-License-Identifier: GPL-2.0-or-later
+-->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.qemu.gdb.riscv.fpu-alias">
+  <reg name="f0" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f1" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f2" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f3" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f4" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f5" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f6" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f7" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f8" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f9" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f10" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f11" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f12" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f13" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f14" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f15" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f16" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f17" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f18" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f19" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f20" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f21" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f22" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f23" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f24" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f25" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f26" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f27" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f28" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f29" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f30" bitsize="32" type="ieee_single" group="qemu-debug"/>
+  <reg name="f31" bitsize="32" type="ieee_single" group="qemu-debug"/>
+</feature>
diff --git a/gdbstub/gdb-xml/riscv-64bit-alias.xml b/gdbstub/gdb-xml/riscv-64bit-alias.xml
new file mode 100644
index 000000000000..28781b230226
--- /dev/null
+++ b/gdbstub/gdb-xml/riscv-64bit-alias.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<!--
+  SPDX-License-Identifier: GPL-2.0-or-later
+-->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.qemu.gdb.riscv.alias">
+  <reg name="x0" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x1" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x2" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x3" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x4" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x5" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x6" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x7" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x8" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x9" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x10" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x11" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x12" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x13" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x14" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x15" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x16" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x17" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x18" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x19" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x20" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x21" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x22" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x23" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x24" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x25" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x26" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x27" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x28" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x29" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x30" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x31" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s0" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x0h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="zeroh" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x1h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="rah" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x2h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="sph" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x3h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="gph" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x4h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="tph" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x5h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="t0h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x6h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="t1h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x7h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="t2h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x8h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s0h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x9h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s1h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x10h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="a0h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x11h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="a1h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x12h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="a2h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x13h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="a3h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x14h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="a4h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x15h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="a5h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x16h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="a6h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x17h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="a7h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x18h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s2h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x19h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s3h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x20h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s4h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x21h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s5h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x22h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s6h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x23h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s7h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x24h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s8h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x25h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s9h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x26h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s10h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x27h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="s11h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x28h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="t3h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x29h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="t4h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x30h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="t5h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="x31h" bitsize="64" type="int" group="qemu-debug"/>
+  <reg name="t6h" bitsize="64" type="int" group="qemu-debug"/>
+</feature>
diff --git a/gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml b/gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml
new file mode 100644
index 000000000000..13e6b341a0f8
--- /dev/null
+++ b/gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+  SPDX-License-Identifier: GPL-2.0-or-later
+-->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.qemu.gdb.riscv.fpu-alias">
+
+  <union id="riscv_double">
+    <field name="float" type="ieee_single"/>
+    <field name="double" type="ieee_double"/>
+  </union>
+
+  <reg name="f0" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f1" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f2" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f3" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f4" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f5" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f6" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f7" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f8" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f9" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f10" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f11" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f12" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f13" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f14" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f15" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f16" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f17" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f18" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f19" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f20" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f21" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f22" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f23" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f24" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f25" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f26" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f27" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f28" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f29" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f30" bitsize="64" type="riscv_double" group="qemu-debug"/>
+  <reg name="f31" bitsize="64" type="riscv_double" group="qemu-debug"/>
+</feature>
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index f279f4ab2461..6694fa86fd84 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -336,16 +336,59 @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
     return &cpu->dyn_vreg_feature;
 }
 
+/* x0-x31, s0, then pairs of numeric and ABI high-half aliases. */
+static int riscv_gdb_get_alias(CPUState *cs, GByteArray *buf, int n)
+{
+    RISCVCPU *cpu = RISCV_CPU(cs);
+    uint64_t val;
+
+    if (n < 33) {
+        return riscv_cpu_gdb_read_register(cs, buf, n == 32 ? 8 : n);
+    }
+
+    val = cpu->env.gprh[(n - 33) / 2];
+    if (riscv_cpu_is_32bit(cpu)) {
+        return gdb_get_reg32(buf, val);
+    }
+    return gdb_get_reg64(buf, val);
+}
+
+static int riscv_gdb_set_alias(CPUState *cs, uint8_t *buf, int n)
+{
+    RISCVCPU *cpu = RISCV_CPU(cs);
+    CPURISCVState *env = &cpu->env;
+    const unsigned regsz = riscv_cpu_is_32bit(cpu) ? 4 : 8;
+
+    if (n < 33) {
+        return riscv_cpu_gdb_write_register(cs, buf, n == 32 ? 8 : n);
+    }
+
+    env->gprh[(n - 33) / 2] = ldn(env, buf, regsz);
+    return regsz;
+}
+
 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
+
+    gdb_register_coprocessor(cs, riscv_gdb_get_alias, riscv_gdb_set_alias,
+                             gdb_find_static_feature(riscv_cpu_is_32bit(cpu) ?
+                                                     "riscv-32bit-alias.xml" :
+                                                     "riscv-64bit-alias.xml"));
+
     if (env->misa_ext & RVD) {
         gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
                                  gdb_find_static_feature("riscv-64bit-fpu.xml"));
+        gdb_register_coprocessor(cs, riscv_gdb_get_fpu,
+            riscv_gdb_set_fpu,
+            gdb_find_static_feature("riscv-64bit-fpu-alias.xml"));
     } else if (env->misa_ext & RVF) {
         gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
                                  gdb_find_static_feature("riscv-32bit-fpu.xml"));
+        gdb_register_coprocessor(cs, riscv_gdb_get_fpu,
+            riscv_gdb_set_fpu,
+            gdb_find_static_feature("riscv-32bit-fpu-alias.xml"));
     }
     if (cpu->cfg.ext_zve32x) {
         GDBFeature *feature =

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* [PATCH 10/10] monitor/hmp: remove legacy MonitorDef infrastructure
  2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
                   ` (8 preceding siblings ...)
  2026-09-11 12:27 ` [PATCH 09/10] target/riscv: expose register aliases via GDB Marc-André Lureau
@ 2026-09-11 12:27 ` Marc-André Lureau
  2026-09-30  8:49 ` [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
  2026-09-30 17:18 ` Philippe Mathieu-Daudé
  11 siblings, 0 replies; 25+ messages in thread
From: Marc-André Lureau @ 2026-09-11 12:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans, Marc-André Lureau

Now that all targets expose their system registers via GDB register
descriptions (i386 segment limits, m68k, sparc64) and $pc is handled by
the CPUClass::get_pc fallback, the legacy MonitorDef table and
SysemuCPUOps::monitor_get_register callback are no longer needed.

Remove MonitorDef struct, the per-target monitor_defs arrays (i386,
m68k, sparc64), riscv_monitor_get_register_legacy(), and the
get_monitor_def() fallback in expr_unary(). HMP $register expressions
now use gdb_get_register_list() exclusively.

For RISC-V, the legacy callback provided case-insensitive register name
matching (e.g. $Mstatus) and a special message for vector
registers ("Unable to print the value of vector vreg"). The GDB-based
lookup is case-sensitive (consistent with all other targets) and reports
oversized registers as "unknown register" instead.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 include/hw/core/sysemu-cpu-ops.h |  16 -----
 include/monitor/hmp.h            |   6 --
 include/qemu/typedefs.h          |   1 -
 monitor/hmp.c                    |  44 +-----------
 target/i386/cpu.c                |  32 ---------
 target/m68k/cpu.c                |  22 ------
 target/riscv/cpu.c               |   1 -
 target/riscv/internals.h         |   3 -
 target/riscv/monitor.c           | 140 ---------------------------------------
 target/sparc/cpu.c               |  19 ------
 10 files changed, 2 insertions(+), 282 deletions(-)

diff --git a/include/hw/core/sysemu-cpu-ops.h b/include/hw/core/sysemu-cpu-ops.h
index e56eea18b785..3a85aa47e243 100644
--- a/include/hw/core/sysemu-cpu-ops.h
+++ b/include/hw/core/sysemu-cpu-ops.h
@@ -101,22 +101,6 @@ typedef struct SysemuCPUOps {
      */
     bool (*internal_is_big_endian)(CPUState *cpu);
 
-    /**
-     * @monitor_get_register: Callback to fill @pval with register @name value.
-     *                        This field is legacy, use @gdb_core_xml_file
-     *                        to dump registers instead.
-     * Returns: 0 on success or negative errno on failure.
-     */
-    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.
      *               Do not use in new targets, use #DeviceClass::vmsd instead.
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index ef53e87f7608..950dd931d452 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -31,12 +31,6 @@ MonitorHMP *monitor_cur_hmp(void);
         g_assert_not_reached(); \
     }
 
-struct MonitorDef {
-    const char *name;
-    int offset;
-    int64_t (*get_value)(MonitorHMP *hmp, const MonitorDef *md, int offset);
-};
-
 void monitor_new_hmp(const char *id, const char *chardev_id,
                      bool use_readline, Error **errp);
 
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 2344c92182ea..5580e1fc4aba 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -72,7 +72,6 @@ typedef struct MemoryRegionSection MemoryRegionSection;
 typedef struct MigrationIncomingState MigrationIncomingState;
 typedef struct MigrationState MigrationState;
 typedef struct Monitor Monitor;
-typedef struct MonitorDef MonitorDef;
 typedef struct MSIMessage MSIMessage;
 typedef struct NetClientState NetClientState;
 typedef struct NetFilterState NetFilterState;
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 0a74247ca66a..f9621ce90aaf 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -24,8 +24,8 @@
 
 #include "qemu/osdep.h"
 #include <dirent.h>
+#include "hw/core/cpu.h"
 #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"
@@ -447,8 +447,6 @@ static bool get_register(MonitorHMP *hmp, int64_t *pval, const char *name)
 static const char *pch;
 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(MonitorHMP *mon, const char *fmt, ...)
 {
@@ -530,8 +528,7 @@ static int64_t expr_unary(MonitorHMP *mon)
                 pch++;
             }
             *q = 0;
-            if (!get_register(mon, &reg, buf)
-                && get_monitor_def(mon, &reg, buf) < 0) {
+            if (!get_register(mon, &reg, buf)) {
                 expr_error(mon, "unknown register");
             }
             n = reg;
@@ -1723,43 +1720,6 @@ void monitor_register_hmp_info_hrt(const char *name,
     g_assert_not_reached();
 }
 
-/*
- * Set @pval to the value in the register identified by @name.
- * return 0 if OK, -1 if not found
- */
-static int get_monitor_def(MonitorHMP *hmp, int64_t *pval, const char *name)
-{
-    CPUState *cs = monitor_hmp_get_cpu(hmp);
-    const MonitorDef *md = NULL;
-    void *ptr;
-
-    if (cs == NULL) {
-        return -1;
-    }
-    md = cs->cc->sysemu_ops->monitor_defs;
-    if (md == NULL) {
-        return -1;
-    }
-
-    for (; md->name != NULL; md++) {
-        if (hmp_compare_cmd(name, md->name)) {
-            if (md->get_value) {
-                *pval = md->get_value(hmp, md, md->offset);
-            } else {
-                CPUArchState *env = monitor_hmp_get_cpu_env(hmp);
-                ptr = (uint8_t *)env + md->offset;
-                *pval = *(int32_t *)ptr;
-            }
-            return 0;
-        }
-    }
-
-    if (!cs->cc->sysemu_ops->monitor_get_register) {
-        return -1;
-    }
-    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);
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b97f144aea5a..3218eae62854 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -42,7 +42,6 @@
 #include "exec/watchpoint.h"
 #ifndef CONFIG_USER_ONLY
 #include "confidential-guest.h"
-#include "monitor/hmp.h"
 #include "system/reset.h"
 #include "qapi/qapi-commands-machine.h"
 #include "system/address-spaces.h"
@@ -10852,34 +10851,6 @@ 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)
-{
-    CPUArchState *env = monitor_hmp_get_cpu_env(hmp);
-    int64_t ret = env->eip + env->segs[R_CS].base;
-
-    if (!(env->hflags & HF_CS64_MASK)) {
-        ret = (int32_t)ret;
-    }
-    return ret;
-}
-
-static const MonitorDef x86_monitor_defs[] = {
-#define SEG(name, seg) \
-    { name ".limit", offsetof(CPUX86State, segs[seg].limit) },
-    SEG("cs", R_CS)
-    SEG("ds", R_DS)
-    SEG("es", R_ES)
-    SEG("ss", R_SS)
-    SEG("fs", R_FS)
-    SEG("gs", R_GS)
-    { "pc", 0, monitor_get_pc, },
-    { NULL },
-#undef SEG
-};
-#endif
-
 #include "hw/core/sysemu-cpu-ops.h"
 
 static const struct SysemuCPUOps i386_sysemu_ops = {
@@ -10893,9 +10864,6 @@ 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 9b52ad5fc234..ad7303305848 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -25,7 +25,6 @@
 #include "disas/capstone.h"
 #ifndef CONFIG_USER_ONLY
 #include "migration/vmstate.h"
-#include "monitor/hmp.h"
 #endif
 
 #include "cpu.h"
@@ -666,32 +665,11 @@ 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]) },
-    { "isp", offsetof(CPUM68KState, sp[2]) },
-    { "sfc", offsetof(CPUM68KState, sfc) },
-    { "dfc", offsetof(CPUM68KState, dfc) },
-    { "urp", offsetof(CPUM68KState, mmu.urp) },
-    { "srp", offsetof(CPUM68KState, mmu.srp) },
-    { "dttr0", offsetof(CPUM68KState, mmu.ttr[M68K_DTTR0]) },
-    { "dttr1", offsetof(CPUM68KState, mmu.ttr[M68K_DTTR1]) },
-    { "ittr0", offsetof(CPUM68KState, mmu.ttr[M68K_ITTR0]) },
-    { "ittr1", offsetof(CPUM68KState, mmu.ttr[M68K_ITTR1]) },
-    { "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/riscv/cpu.c b/target/riscv/cpu.c
index 5fff9d745e9b..9a57873ea5d3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -3015,7 +3015,6 @@ static const struct SysemuCPUOps riscv_sysemu_ops = {
     .legacy_vmsd = &vmstate_riscv_cpu,
 #ifdef CONFIG_TCG
     .translate_for_debug = riscv_cpu_translate_for_debug,
-    .monitor_get_register = riscv_monitor_get_register_legacy,
 #endif
 };
 #endif
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 5d84e4de960a..09aa2701197e 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -263,7 +263,4 @@ static inline int insn_len(uint16_t first_word)
     return (first_word & 3) == 3 ? 4 : 2;
 }
 
-int riscv_monitor_get_register_legacy(CPUState *cs, const char *name,
-                                      int64_t *pval);
-
 #endif
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
index 7e61ae2a4717..20f3ba57ae57 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -19,10 +19,7 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu/ctype.h"
-#include "qemu/qemu-print.h"
 #include "cpu.h"
-#include "target/riscv/tcg/csr.h"
 #include "cpu_bits.h"
 #include "monitor/monitor.h"
 #include "monitor/hmp.h"
@@ -247,140 +244,3 @@ 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,
-                                 target_ulong *val, bool is_gprh)
-{
-    const char * const *reg_names;
-    uint64_t *vals;
-
-    if (is_gprh) {
-        reg_names = riscv_int_regnamesh;
-        vals = env->gprh;
-    } else {
-        reg_names = riscv_int_regnames;
-        vals = env->gpr;
-    }
-
-    for (int i = 0; i < 32; i++) {
-        g_auto(GStrv) reg_name = g_strsplit(reg_names[i], "/", 2);
-
-        g_assert(reg_name[0]);
-        g_assert(reg_name[1]);
-
-        if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
-            g_ascii_strcasecmp(reg_name[1], name) == 0) {
-            *val = vals[i];
-            return true;
-        }
-    }
-
-    return false;
-}
-
-static bool reg_is_u64_fpu(CPURISCVState *env, const char *name, uint64_t *val)
-{
-    if (qemu_tolower(name[0]) != 'f') {
-        return false;
-    }
-
-    for (int i = 0; i < 32; i++) {
-        g_auto(GStrv) reg_name = g_strsplit(riscv_fpr_regnames[i], "/", 2);
-
-        g_assert(reg_name[0]);
-        g_assert(reg_name[1]);
-
-        if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
-            g_ascii_strcasecmp(reg_name[1], name) == 0) {
-            *val = env->fpr[i];
-            return true;
-        }
-    }
-
-    return false;
-}
-
-static bool reg_is_vreg(const char *name)
-{
-    if (qemu_tolower(name[0]) != 'v' || strlen(name) > 3) {
-        return false;
-    }
-
-    for (int i = 0; i < 32; i++) {
-        if (g_ascii_strcasecmp(name, riscv_rvv_regnames[i]) == 0) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-int riscv_monitor_get_register_legacy(CPUState *cs, const char *name,
-                                      int64_t *pval)
-{
-    RISCVCPU *hart = RISCV_CPU(cs);
-    CPURISCVState *env = cpu_env(cs);
-    target_ulong val = 0;
-    uint64_t val64 = 0;
-    int i;
-
-    if (reg_is_ulong_integer(env, name, &val, false) ||
-        reg_is_ulong_integer(env, name, &val, true)) {
-        *pval = riscv_cpu_is_32bit(hart) ? (int32_t)val : val;
-        return 0;
-    }
-
-    if (reg_is_u64_fpu(env, name, &val64)) {
-        *pval = val64;
-        return 0;
-    }
-
-    if (reg_is_vreg(name)) {
-        if (!riscv_cpu_cfg(env)->ext_zve32x) {
-            return -EINVAL;
-        }
-
-        qemu_printf("Unable to print the value of vector "
-                    "vreg '%s' from this API\n", name);
-
-        /*
-         * We're returning 0 because returning -EINVAL triggers
-         * an 'unknown register' message in exp_unary() later,
-         * which feels ankward after our own error message.
-         */
-        *pval = 0;
-        return 0;
-    }
-
-    for (i = 0; i < ARRAY_SIZE(csr_ops); i++) {
-        RISCVException res;
-        int csrno = i;
-
-        /*
-         * Early skip when possible since we're going
-         * through a lot of NULL entries.
-         */
-        if (csr_ops[csrno].predicate == NULL) {
-            continue;
-        }
-
-        if (g_ascii_strcasecmp(csr_ops[csrno].name, name) != 0) {
-            continue;
-        }
-
-        res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
-
-        /*
-         * Rely on the smode, hmode, etc, predicates within csr.c
-         * to do the filtering of the registers that are present.
-         */
-        if (res == RISCV_EXCP_NONE) {
-            *pval = riscv_cpu_is_32bit(hart) ? (int32_t)val : val;
-            return 0;
-        }
-    }
-
-    return -EINVAL;
-}
-#endif
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index ae9bdca9df82..89dfb091ca87 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -995,31 +995,12 @@ static const Property sparc_cpu_properties[] = {
 
 #ifndef CONFIG_USER_ONLY
 
-#ifdef TARGET_SPARC64
-#include "monitor/hmp.h"
-#ifdef CONFIG_HMP
-static const MonitorDef sparc64_monitor_defs[] = {
-    { "asi", offsetof(CPUSPARCState, asi) },
-    { "pstate", offsetof(CPUSPARCState, pstate) },
-    { "cansave", offsetof(CPUSPARCState, cansave) },
-    { "canrestore", offsetof(CPUSPARCState, canrestore) },
-    { "otherwin", offsetof(CPUSPARCState, otherwin) },
-    { "wstate", offsetof(CPUSPARCState, wstate) },
-    { "cleanwin", offsetof(CPUSPARCState, cleanwin) },
-    { NULL },
-};
-#endif
-#endif
-
 #include "hw/core/sysemu-cpu-ops.h"
 
 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) && defined(CONFIG_HMP)
-    .monitor_defs = sparc64_monitor_defs,
-#endif
 };
 #endif
 

-- 
2.55.0.543.g5ebe2ebe4ea8



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

* Re: [PATCH 02/10] gdbstub: fix next register base after register gaps
  2026-09-11 12:27 ` [PATCH 02/10] gdbstub: fix next register base after register gaps Marc-André Lureau
@ 2026-09-11 15:29   ` Alex Bennée
  0 siblings, 0 replies; 25+ messages in thread
From: Alex Bennée @ 2026-09-11 15:29 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: qemu-devel, Dr. David Alan Gilbert, Philippe Mathieu-Daudé,
	Zhao Liu, Peter Maydell, Chinmay Rath, Nicholas Piggin,
	Glenn Miles, Harsh Prateek Bora, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu,
	Max Filippov, qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini,
	Laurent Vivier, Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans

Marc-André Lureau <marcandre.lureau@redhat.com> writes:

> Commit b3e88abb200c ("gdbstub: Consider GDBFeature::base_reg in
> gdb_register_coprocessor()") identified that register numbers may
> have gaps. We also need to adjust the next base_reg correctly
> to avoid overlapping registers. Rename the field to be more
> explicit about its usage.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Acked-by: Alex Bennée <alex.bennee@linaro.org>

> ---
>  gdbstub/gdbstub.c      | 13 ++++++-------
>  include/hw/core/cpu.h  |  2 +-
>  target/arm/gdbstub.c   |  8 +++++---
>  target/arm/gdbstub64.c | 10 ++++++----
>  target/ppc/gdbstub.c   |  2 +-
>  target/riscv/gdbstub.c |  9 ++++++---
>  target/xtensa/cpu.c    |  2 +-
>  7 files changed, 26 insertions(+), 20 deletions(-)
>
> diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
> index 0a328b0dd488..0ce871d74929 100644
> --- a/gdbstub/gdbstub.c
> +++ b/gdbstub/gdbstub.c
> @@ -605,13 +605,13 @@ void gdb_init_cpu(CPUState *cpu)
>          gdb_register_feature(cpu, 0,
>                               cc->gdb_read_register, cc->gdb_write_register,
>                               feature);
> -        cpu->gdb_num_regs = cpu->gdb_num_g_regs = feature->num_regs;
> +        cpu->gdb_next_base_reg = cpu->gdb_num_g_regs = feature->num_regs;
>      } else {
> -        cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
> +        cpu->gdb_next_base_reg = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
>      }
>  
>      trace_gdbxml_init_cpu(object_get_typename(OBJECT(cpu)), cpu->cpu_index,
> -                          cpu->gdb_num_regs, cpu->gdb_num_g_regs,
> +                          cpu->gdb_next_base_reg, cpu->gdb_num_g_regs,
>                            cc->gdb_num_core_regs);
>  }
>  
> @@ -621,7 +621,7 @@ void gdb_register_coprocessor(CPUState *cpu,
>  {
>      GDBRegisterState *s;
>      guint i;
> -    int base_reg = cpu->gdb_num_regs;
> +    int base_reg = cpu->gdb_next_base_reg;
>  
>      for (i = 0; i < cpu->gdb_regs->len; i++) {
>          /* Check for duplicates.  */
> @@ -639,7 +639,7 @@ void gdb_register_coprocessor(CPUState *cpu,
>      gdb_register_feature(cpu, base_reg, get_reg, set_reg, feature);
>  
>      /* Add to end of list.  */
> -    cpu->gdb_num_regs += feature->num_regs;
> +    cpu->gdb_next_base_reg = base_reg + feature->num_regs;
>  }
>  
>  void gdb_unregister_coprocessor_all(CPUState *cpu)
> @@ -651,7 +651,7 @@ void gdb_unregister_coprocessor_all(CPUState *cpu)
>      g_array_free(cpu->gdb_regs, true);
>  
>      cpu->gdb_regs = NULL;
> -    cpu->gdb_num_regs = 0;
> +    cpu->gdb_next_base_reg = 0;
>      cpu->gdb_num_g_regs = 0;
>  }
>  
> @@ -2522,4 +2522,3 @@ void gdb_create_default_process(GDBState *s)
>      process->attached = false;
>      process->target_xml = NULL;
>  }
> -
> diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
> index 328e30045ce1..02212f555c2e 100644
> --- a/include/hw/core/cpu.h
> +++ b/include/hw/core/cpu.h
> @@ -521,7 +521,7 @@ struct CPUState {
>      struct CPUJumpCache *tb_jmp_cache;
>  
>      GArray *gdb_regs;
> -    int gdb_num_regs;
> +    int gdb_next_base_reg;
>      int gdb_num_g_regs;
>      QTAILQ_ENTRY(CPUState) node;
>  
> diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
> index d6e29c4cf467..e5cbe4d951ef 100644
> --- a/target/arm/gdbstub.c
> +++ b/target/arm/gdbstub.c
> @@ -555,19 +555,21 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
>          gdb_register_coprocessor(cs, mve_gdb_get_reg, mve_gdb_set_reg,
>                                   gdb_find_static_feature("arm-m-profile-mve.xml"));
>      }
> +    GDBFeature *feature =
> +        arm_gen_dynamic_sysreg_feature(cs, cs->gdb_next_base_reg);
>      gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
> -                             arm_gen_dynamic_sysreg_feature(cs, cs->gdb_num_regs));
> +                             feature);
>  
>  #ifdef CONFIG_TCG
>      if (arm_feature(env, ARM_FEATURE_M) && tcg_enabled()) {
>          gdb_register_coprocessor(cs,
>              arm_gdb_get_m_systemreg, arm_gdb_set_m_systemreg,
> -            arm_gen_dynamic_m_systemreg_feature(cs, cs->gdb_num_regs));
> +            arm_gen_dynamic_m_systemreg_feature(cs, cs->gdb_next_base_reg));
>  #ifndef CONFIG_USER_ONLY
>          if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
>              gdb_register_coprocessor(cs,
>                  arm_gdb_get_m_secextreg, arm_gdb_set_m_secextreg,
> -                arm_gen_dynamic_m_secextreg_feature(cs, cs->gdb_num_regs));
> +                arm_gen_dynamic_m_secextreg_feature(cs, cs->gdb_next_base_reg));
>          }
>  #endif
>      }
> diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
> index 0c3e5b30bd6a..cf5b95b54641 100644
> --- a/target/arm/gdbstub64.c
> +++ b/target/arm/gdbstub64.c
> @@ -885,7 +885,8 @@ void aarch64_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
>      CPUState *cs = CPU(cpu);
>      if (isar_feature_aa64_sve(&cpu->isar) ||
>          isar_feature_aa64_sme(&cpu->isar)) {
> -        GDBFeature *feature = arm_gen_dynamic_svereg_feature(cs, cs->gdb_num_regs);
> +        GDBFeature *feature =
> +            arm_gen_dynamic_svereg_feature(cs, cs->gdb_next_base_reg);
>          gdb_register_coprocessor(cs, aarch64_gdb_get_sve_reg,
>                                   aarch64_gdb_set_sve_reg, feature);
>      } else {
> @@ -896,7 +897,7 @@ void aarch64_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
>  
>      if (isar_feature_aa64_sme(&cpu->isar)) {
>          GDBFeature *sme_feature =
> -            arm_gen_dynamic_smereg_feature(cs, cs->gdb_num_regs);
> +            arm_gen_dynamic_smereg_feature(cs, cs->gdb_next_base_reg);
>          gdb_register_coprocessor(cs, aarch64_gdb_get_sme_reg,
>                                   aarch64_gdb_set_sme_reg, sme_feature);
>          if (isar_feature_aa64_sme2(&cpu->isar)) {
> @@ -927,7 +928,8 @@ void aarch64_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
>  #endif
>  
>      /* All AArch64 CPUs have at least TPIDR */
> +    GDBFeature *tls_feature =
> +        arm_gen_dynamic_tls_feature(cs, cs->gdb_next_base_reg);
>      gdb_register_coprocessor(cs, aarch64_gdb_get_tls_reg,
> -                             aarch64_gdb_set_tls_reg,
> -                             arm_gen_dynamic_tls_feature(cs, cs->gdb_num_regs));
> +                             aarch64_gdb_set_tls_reg, tls_feature);
>  }
> diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c
> index 4d622c5cad59..ec25c541c685 100644
> --- a/target/ppc/gdbstub.c
> +++ b/target/ppc/gdbstub.c
> @@ -206,7 +206,7 @@ static void gdb_gen_spr_feature(CPUState *cs)
>  
>      gdb_feature_builder_init(&builder, &pcc->gdb_spr,
>                               "org.qemu.power.spr", "power-spr.xml",
> -                             cs->gdb_num_regs);
> +                             cs->gdb_next_base_reg);
>  
>      for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
>          ppc_spr_t *spr = &env->spr_cb[i];
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index 9abbf5bcdf0e..f279f4ab2461 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -348,9 +348,10 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
>                                   gdb_find_static_feature("riscv-32bit-fpu.xml"));
>      }
>      if (cpu->cfg.ext_zve32x) {
> +        GDBFeature *feature =
> +            ricsv_gen_dynamic_vector_feature(cs, cs->gdb_next_base_reg);
>          gdb_register_coprocessor(cs, riscv_gdb_get_vector,
> -                                 riscv_gdb_set_vector,
> -                                 ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs));
> +                                 riscv_gdb_set_vector, feature);
>      }
>  
>  #ifdef CONFIG_TCG
> @@ -373,8 +374,10 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
>      }
>  
>      if (cpu->cfg.ext_zicsr) {
> +        GDBFeature *feature =
> +            riscv_gen_dynamic_csr_feature(cs, cs->gdb_next_base_reg);
>          gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
> -                                 riscv_gen_dynamic_csr_feature(cs, cs->gdb_num_regs));
> +                                 feature);
>      }
>  #endif
>  }
> diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
> index 7c25b9ab707a..48863a1859d4 100644
> --- a/target/xtensa/cpu.c
> +++ b/target/xtensa/cpu.c
> @@ -263,7 +263,7 @@ static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
>          return;
>      }
>  
> -    cs->gdb_num_regs = xcc->config->gdb_regmap.num_regs;
> +    cs->gdb_next_base_reg = xcc->config->gdb_regmap.num_regs;
>  
>      qemu_init_vcpu(cs);

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro


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

* Re: [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers
  2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
                   ` (9 preceding siblings ...)
  2026-09-11 12:27 ` [PATCH 10/10] monitor/hmp: remove legacy MonitorDef infrastructure Marc-André Lureau
@ 2026-09-30  8:49 ` Marc-André Lureau
  2026-09-30 17:18 ` Philippe Mathieu-Daudé
  11 siblings, 0 replies; 25+ messages in thread
From: Marc-André Lureau @ 2026-09-30  8:49 UTC (permalink / raw)
  To: qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans

Hi

On Fri, Sep 11, 2026 at 4:28 PM Marc-André Lureau
<marcandre.lureau@redhat.com> wrote:
>
> Hi,
>
> HMP monitor supports printing $register expression. The lookup
> was done via GDB stub registers, and supplementary MonitorDef
> HMP-specific tables.
>
> Migrate HMP registers to use the GDB infrastructure and remove the
> legacy HMP MonitorDef. Use a "qemu-debug" register group, as they are
> aliases or synthetic registers, but gdb doesn't seem to care.
>
> Known behavioural changes on RISC-V: CSR lookup is now case-sensitive
> and vector registers now report "unkown register" instead of a
> target-specific message ("Unable to print the value of vector vreg 'v0'
> from this API")
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

ping? swap reviews?

> ---
> Marc-André Lureau (10):
>       hmp: don't crash on invalid register
>       gdbstub: fix next register base after register gaps
>       gdbstub: set feature->base_reg for dynamic features
>       target/i386: expose segment limits via GDB
>       monitor/hmp: add CPUClass::get_pc fallback for HMP $pc
>       target/m68k: expose system registers via GDB
>       target/sparc64: expose system registers via GDB
>       target/riscv: bypass smstateen check in debugger mode
>       target/riscv: expose register aliases via GDB
>       monitor/hmp: remove legacy MonitorDef infrastructure
>
>  configs/targets/i386-softmmu.mak          |   2 +-
>  configs/targets/m68k-softmmu.mak          |   2 +-
>  configs/targets/riscv32-linux-user.mak    |   2 +-
>  configs/targets/riscv32-softmmu.mak       |   2 +-
>  configs/targets/riscv64-bsd-user.mak      |   2 +-
>  configs/targets/riscv64-linux-user.mak    |   2 +-
>  configs/targets/riscv64-softmmu.mak       |   2 +-
>  configs/targets/sparc64-softmmu.mak       |   2 +-
>  configs/targets/x86_64-softmmu.mak        |   2 +-
>  gdbstub/gdb-xml/i386-segments.xml         |  14 +++
>  gdbstub/gdb-xml/m68k-system.xml           |  32 +++++++
>  gdbstub/gdb-xml/riscv-32bit-alias.xml     | 105 ++++++++++++++++++++++
>  gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml |  40 +++++++++
>  gdbstub/gdb-xml/riscv-64bit-alias.xml     | 105 ++++++++++++++++++++++
>  gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml |  46 ++++++++++
>  gdbstub/gdb-xml/sparc64-system.xml        |  22 +++++
>  gdbstub/gdbstub.c                         |  14 +--
>  include/hw/core/cpu.h                     |   2 +-
>  include/hw/core/sysemu-cpu-ops.h          |  16 ----
>  include/monitor/hmp.h                     |   6 --
>  include/qemu/typedefs.h                   |   1 -
>  monitor/hmp.c                             |  52 ++---------
>  target/arm/gdbstub.c                      |   8 +-
>  target/arm/gdbstub64.c                    |  10 ++-
>  target/i386/cpu.c                         |  32 -------
>  target/i386/gdbstub.c                     |  24 +++++
>  target/m68k/cpu.c                         |  22 -----
>  target/m68k/helper.c                      |  47 ++++++++++
>  target/ppc/gdbstub.c                      |   2 +-
>  target/riscv/cpu.c                        |   1 -
>  target/riscv/gdbstub.c                    |  52 ++++++++++-
>  target/riscv/internals.h                  |   3 -
>  target/riscv/monitor.c                    | 140 ------------------------------
>  target/riscv/tcg/csr.c                    |   3 +-
>  target/sparc/cpu.c                        |  19 ----
>  target/sparc/gdbstub.c                    |  38 ++++++++
>  target/xtensa/cpu.c                       |   2 +-
>  37 files changed, 562 insertions(+), 314 deletions(-)
> ---
> base-commit: 209b2afaface001c7d4d981e38f186afe7b24a50
> change-id: 20260910-query-reg-80cd59cf4707
>
> Best regards,
> --
> Marc-André Lureau <marcandre.lureau@redhat.com>
>
>


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

* Re: [PATCH 01/10] hmp: don't crash on invalid register
  2026-09-11 12:27 ` [PATCH 01/10] hmp: don't crash on invalid register Marc-André Lureau
@ 2026-09-30 16:59   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 25+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-30 16:59 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans

On 11/9/26 14:27, Marc-André Lureau wrote:
> When printing an invalid/denied register, QEMU crashes with:
> ERROR:include/qemu/bswap.h:488:ldn_le_p: code should not be reached
> 
> (ex: "p $sireg" when siselect=0 on riscv)
> 
> Return false instead.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   monitor/hmp.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)

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


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

* Re: [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers
  2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
                   ` (10 preceding siblings ...)
  2026-09-30  8:49 ` [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
@ 2026-09-30 17:18 ` Philippe Mathieu-Daudé
  2026-10-01  8:00   ` Akihiko Odaki
  11 siblings, 1 reply; 25+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-30 17:18 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel, Akihiko Odaki
  Cc: Dr. David Alan Gilbert, Alex Bennée, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans

Cc'ing Akihiko who worked on gdbstub.

On 11/9/26 14:27, Marc-André Lureau wrote:
> Hi,
> 
> HMP monitor supports printing $register expression. The lookup
> was done via GDB stub registers, and supplementary MonitorDef
> HMP-specific tables.
> 
> Migrate HMP registers to use the GDB infrastructure and remove the
> legacy HMP MonitorDef. Use a "qemu-debug" register group, as they are
> aliases or synthetic registers, but gdb doesn't seem to care.
> 
> Known behavioural changes on RISC-V: CSR lookup is now case-sensitive
> and vector registers now report "unkown register" instead of a
> target-specific message ("Unable to print the value of vector vreg 'v0'
> from this API")
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> Marc-André Lureau (10):
>        hmp: don't crash on invalid register
>        gdbstub: fix next register base after register gaps
>        gdbstub: set feature->base_reg for dynamic features
>        target/i386: expose segment limits via GDB
>        monitor/hmp: add CPUClass::get_pc fallback for HMP $pc
>        target/m68k: expose system registers via GDB
>        target/sparc64: expose system registers via GDB
>        target/riscv: bypass smstateen check in debugger mode
>        target/riscv: expose register aliases via GDB
>        monitor/hmp: remove legacy MonitorDef infrastructure
> 
>   configs/targets/i386-softmmu.mak          |   2 +-
>   configs/targets/m68k-softmmu.mak          |   2 +-
>   configs/targets/riscv32-linux-user.mak    |   2 +-
>   configs/targets/riscv32-softmmu.mak       |   2 +-
>   configs/targets/riscv64-bsd-user.mak      |   2 +-
>   configs/targets/riscv64-linux-user.mak    |   2 +-
>   configs/targets/riscv64-softmmu.mak       |   2 +-
>   configs/targets/sparc64-softmmu.mak       |   2 +-
>   configs/targets/x86_64-softmmu.mak        |   2 +-
>   gdbstub/gdb-xml/i386-segments.xml         |  14 +++
>   gdbstub/gdb-xml/m68k-system.xml           |  32 +++++++
>   gdbstub/gdb-xml/riscv-32bit-alias.xml     | 105 ++++++++++++++++++++++
>   gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml |  40 +++++++++
>   gdbstub/gdb-xml/riscv-64bit-alias.xml     | 105 ++++++++++++++++++++++
>   gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml |  46 ++++++++++
>   gdbstub/gdb-xml/sparc64-system.xml        |  22 +++++
>   gdbstub/gdbstub.c                         |  14 +--
>   include/hw/core/cpu.h                     |   2 +-
>   include/hw/core/sysemu-cpu-ops.h          |  16 ----
>   include/monitor/hmp.h                     |   6 --
>   include/qemu/typedefs.h                   |   1 -
>   monitor/hmp.c                             |  52 ++---------
>   target/arm/gdbstub.c                      |   8 +-
>   target/arm/gdbstub64.c                    |  10 ++-
>   target/i386/cpu.c                         |  32 -------
>   target/i386/gdbstub.c                     |  24 +++++
>   target/m68k/cpu.c                         |  22 -----
>   target/m68k/helper.c                      |  47 ++++++++++
>   target/ppc/gdbstub.c                      |   2 +-
>   target/riscv/cpu.c                        |   1 -
>   target/riscv/gdbstub.c                    |  52 ++++++++++-
>   target/riscv/internals.h                  |   3 -
>   target/riscv/monitor.c                    | 140 ------------------------------
>   target/riscv/tcg/csr.c                    |   3 +-
>   target/sparc/cpu.c                        |  19 ----
>   target/sparc/gdbstub.c                    |  38 ++++++++
>   target/xtensa/cpu.c                       |   2 +-
>   37 files changed, 562 insertions(+), 314 deletions(-)
> ---
> base-commit: 209b2afaface001c7d4d981e38f186afe7b24a50
> change-id: 20260910-query-reg-80cd59cf4707
> 
> Best regards,
> --
> Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> 



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

* Re: [PATCH 03/10] gdbstub: set feature->base_reg for dynamic features
  2026-09-11 12:27 ` [PATCH 03/10] gdbstub: set feature->base_reg for dynamic features Marc-André Lureau
@ 2026-09-30 17:18   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 25+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-30 17:18 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans

On 11/9/26 14:27, Marc-André Lureau wrote:
> gdb_feature_builder_end() never propagated builder->base_reg into
> feature->base_reg, leaving it at 0 for all dynamically-built features.
> This made the trace log at gdb_get_register_list() report an incorrect
> base_reg for dynamic features.
> 
> GDBRegisterState::base_reg was correctly set, so this doesn't fix
> an actual issue.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   gdbstub/gdbstub.c | 1 +
>   1 file changed, 1 insertion(+)

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


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

* Re: [PATCH 05/10] monitor/hmp: add CPUClass::get_pc fallback for HMP $pc
  2026-09-11 12:27 ` [PATCH 05/10] monitor/hmp: add CPUClass::get_pc fallback for HMP $pc Marc-André Lureau
@ 2026-09-30 17:31   ` Philippe Mathieu-Daudé
  2026-10-01  4:17     ` Akihiko Odaki
  0 siblings, 1 reply; 25+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-30 17:31 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans

On 11/9/26 14:27, Marc-André Lureau wrote:
> Some targets, including x86, have no GDB register named "pc" (x86
> uses eip/rip). When the GDB register lookup fails for "$pc" in
> HMP expressions, fall back to CPUClass::get_pc so that "p $pc",
> "x $pc" etc. work without relying on the legacy MonitorDef table.
> 
> This prepares for the eventual removal of MonitorDef while making
> $pc available immediately for all targets that implement get_pc.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   monitor/hmp.c | 8 ++++++--
>   1 file changed, 6 insertions(+), 2 deletions(-)


> @@ -435,6 +435,10 @@ static bool gdb_get_register(MonitorHMP *hmp, int64_t *pval, const char *name)

> +    if (!strcmp(name, "pc") && cs->cc->get_pc) {
> +        *pval = cs->cc->get_pc(cs);
> +        return true;
> +    }
>       return false;
>   }
Before commit 57206fd42a0 ("more register values in monitor") we had
$eip (32-bit) aliased as $pc, but I suppose in order to add the 64-bit
port (see next commit, 75dfaa1e64b "x86-64 port (Jocelyn Mayer)") it
was unified as a single $pc instead of adding the corresponding $rip:

-    { "eip|pc", offsetof(CPUState, eip) },
+    { "pc", 0, monitor_get_pc, },

This was 22 years ago :) With retrospective I'd say a generic $pc is
misleading (note, this is only for the x86 architecture, the other
ones don't suffer from this problem).

To be pedantic we could add a 'const char *CPUClass::get_pc_regname()'
helper, but TBH I'd just drop this and let the monitor reports an error.
gdbstub doesn't suffer from that because EIP/RIP register index are
used.

What is the community view on this?


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

* Re: [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode
  2026-09-11 12:27 ` [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode Marc-André Lureau
@ 2026-09-30 18:24   ` Daniel Henrique Barboza
  2026-10-01  0:57       ` Chao Liu via
  0 siblings, 1 reply; 25+ messages in thread
From: Daniel Henrique Barboza @ 2026-09-30 18:24 UTC (permalink / raw)
  To: Marc-André Lureau, qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée,
	Philippe Mathieu-Daudé, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li, Liu Zhiwei, Chao Liu,
	Max Filippov, qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini,
	Laurent Vivier, Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans



On 9/11/2026 9:27 AM, Marc-André Lureau wrote:
> Allow to read CSRs gated by Smstateen extension when env->debugger.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   target/riscv/tcg/csr.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c
> index bd4b6dc114bc..93a7f419f29f 100644
> --- a/target/riscv/tcg/csr.c
> +++ b/target/riscv/tcg/csr.c
> @@ -53,7 +53,8 @@ RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
>   {
>       bool virt = env->virt_enabled;
>   
> -    if (env->priv == PRV_M || !riscv_cpu_cfg(env)->ext_smstateen) {
> +    if (env->debugger || env->priv == PRV_M ||
> +        !riscv_cpu_cfg(env)->ext_smstateen) {

We have an going work in qemu-riscv (sdext, currently on v10) that adds
a new 'debug' mode that is higher than the machine mode (PRV_M).  It
already uses env->debugger in its logic.

I believe this change is already in line with what we want there, i.e. debug
mode having at least the same accesses as PRV_M.


Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>



>           return RISCV_EXCP_NONE;
>       }
>   
> 



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

* Re: [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode
  2026-09-30 18:24   ` Daniel Henrique Barboza
  2026-10-01  0:57       ` Chao Liu via
@ 2026-10-01  0:57       ` Chao Liu via
  0 siblings, 0 replies; 25+ messages in thread
From: Chao Liu via qemu development @ 2026-10-01  0:57 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: Marc-André Lureau, qemu-devel, Dr. David Alan Gilbert,
	Alex Bennée, Philippe Mathieu-Daudé, Zhao Liu,
	Peter Maydell, Chinmay Rath, Nicholas Piggin, Glenn Miles,
	Harsh Prateek Bora, Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Liu Zhiwei, Max Filippov, qemu-arm, qemu-ppc, qemu-riscv,
	Paolo Bonzini, Laurent Vivier, Mark Cave-Ayland, Artyom Tarasenko,
	Helge Deller, Pierrick Bouvier, Warner Losh, Kyle Evans

On Wed, Sep 30, 2026 at 03:24:34PM +0800, Daniel Henrique Barboza wrote:
> 
> 
> On 9/11/2026 9:27 AM, Marc-André Lureau wrote:
> > Allow to read CSRs gated by Smstateen extension when env->debugger.
> > 
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> >   target/riscv/tcg/csr.c | 3 ++-
> >   1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c
> > index bd4b6dc114bc..93a7f419f29f 100644
> > --- a/target/riscv/tcg/csr.c
> > +++ b/target/riscv/tcg/csr.c
> > @@ -53,7 +53,8 @@ RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
> >   {
> >       bool virt = env->virt_enabled;
> > -    if (env->priv == PRV_M || !riscv_cpu_cfg(env)->ext_smstateen) {
> > +    if (env->debugger || env->priv == PRV_M ||
> > +        !riscv_cpu_cfg(env)->ext_smstateen) {
> 
> We have an going work in qemu-riscv (sdext, currently on v10) that adds
> a new 'debug' mode that is higher than the machine mode (PRV_M).  It
> already uses env->debugger in its logic.
> 
Looks good to me. Debug Mode uses M-mode privileges as a baseline, with
additional access to debug-only CSRs.

One thought came to mind here that I'd like to share: for CSR access,
`env->debugger` and 'debug' mode both indicate a debugging context,
entered through QEMU's GDB stub or the CPU's architectural debug
mechanism. CSR access rules differ in that context.

I think a shared helper could check these two flags together,
and include `PRV_M` where the same access rules apply. This is outside
the scope of this patch, but we can look into it once Sdext is merged.
I'll work on it if I have time.


Reviewed-by: Chao Liu <chao.liu@processmission.com>

Thanks,
Chao

> I believe this change is already in line with what we want there, i.e. debug
> mode having at least the same accesses as PRV_M.
> 
> 
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> 
> 
> 
> >           return RISCV_EXCP_NONE;
> >       }
> > 
> 


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

* Re: [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode
@ 2026-10-01  0:57       ` Chao Liu via
  0 siblings, 0 replies; 25+ messages in thread
From: Chao Liu via @ 2026-10-01  0:57 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: Marc-André Lureau, qemu-devel, Dr. David Alan Gilbert,
	Alex Bennée, Philippe Mathieu-Daudé, Zhao Liu,
	Peter Maydell, Chinmay Rath, Nicholas Piggin, Glenn Miles,
	Harsh Prateek Bora, Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Liu Zhiwei, Max Filippov, qemu-arm, qemu-ppc, qemu-riscv,
	Paolo Bonzini, Laurent Vivier, Mark Cave-Ayland, Artyom Tarasenko,
	Helge Deller, Pierrick Bouvier, Warner Losh, Kyle Evans

On Wed, Sep 30, 2026 at 03:24:34PM +0800, Daniel Henrique Barboza wrote:
> 
> 
> On 9/11/2026 9:27 AM, Marc-André Lureau wrote:
> > Allow to read CSRs gated by Smstateen extension when env->debugger.
> > 
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> >   target/riscv/tcg/csr.c | 3 ++-
> >   1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c
> > index bd4b6dc114bc..93a7f419f29f 100644
> > --- a/target/riscv/tcg/csr.c
> > +++ b/target/riscv/tcg/csr.c
> > @@ -53,7 +53,8 @@ RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
> >   {
> >       bool virt = env->virt_enabled;
> > -    if (env->priv == PRV_M || !riscv_cpu_cfg(env)->ext_smstateen) {
> > +    if (env->debugger || env->priv == PRV_M ||
> > +        !riscv_cpu_cfg(env)->ext_smstateen) {
> 
> We have an going work in qemu-riscv (sdext, currently on v10) that adds
> a new 'debug' mode that is higher than the machine mode (PRV_M).  It
> already uses env->debugger in its logic.
> 
Looks good to me. Debug Mode uses M-mode privileges as a baseline, with
additional access to debug-only CSRs.

One thought came to mind here that I'd like to share: for CSR access,
`env->debugger` and 'debug' mode both indicate a debugging context,
entered through QEMU's GDB stub or the CPU's architectural debug
mechanism. CSR access rules differ in that context.

I think a shared helper could check these two flags together,
and include `PRV_M` where the same access rules apply. This is outside
the scope of this patch, but we can look into it once Sdext is merged.
I'll work on it if I have time.


Reviewed-by: Chao Liu <chao.liu@processmission.com>

Thanks,
Chao

> I believe this change is already in line with what we want there, i.e. debug
> mode having at least the same accesses as PRV_M.
> 
> 
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> 
> 
> 
> >           return RISCV_EXCP_NONE;
> >       }
> > 
> 


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

* Re: [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode
@ 2026-10-01  0:57       ` Chao Liu via
  0 siblings, 0 replies; 25+ messages in thread
From: Chao Liu via @ 2026-10-01  0:57 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: Marc-André Lureau, qemu-devel, Dr. David Alan Gilbert,
	Alex Bennée, Philippe Mathieu-Daudé, Zhao Liu,
	Peter Maydell, Chinmay Rath, Nicholas Piggin, Glenn Miles,
	Harsh Prateek Bora, Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Liu Zhiwei, Max Filippov, qemu-arm, qemu-ppc, qemu-riscv,
	Paolo Bonzini, Laurent Vivier, Mark Cave-Ayland, Artyom Tarasenko,
	Helge Deller, Pierrick Bouvier, Warner Losh, Kyle Evans

On Wed, Sep 30, 2026 at 03:24:34PM +0800, Daniel Henrique Barboza wrote:
> 
> 
> On 9/11/2026 9:27 AM, Marc-André Lureau wrote:
> > Allow to read CSRs gated by Smstateen extension when env->debugger.
> > 
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> >   target/riscv/tcg/csr.c | 3 ++-
> >   1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c
> > index bd4b6dc114bc..93a7f419f29f 100644
> > --- a/target/riscv/tcg/csr.c
> > +++ b/target/riscv/tcg/csr.c
> > @@ -53,7 +53,8 @@ RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
> >   {
> >       bool virt = env->virt_enabled;
> > -    if (env->priv == PRV_M || !riscv_cpu_cfg(env)->ext_smstateen) {
> > +    if (env->debugger || env->priv == PRV_M ||
> > +        !riscv_cpu_cfg(env)->ext_smstateen) {
> 
> We have an going work in qemu-riscv (sdext, currently on v10) that adds
> a new 'debug' mode that is higher than the machine mode (PRV_M).  It
> already uses env->debugger in its logic.
> 
Looks good to me. Debug Mode uses M-mode privileges as a baseline, with
additional access to debug-only CSRs.

One thought came to mind here that I'd like to share: for CSR access,
`env->debugger` and 'debug' mode both indicate a debugging context,
entered through QEMU's GDB stub or the CPU's architectural debug
mechanism. CSR access rules differ in that context.

I think a shared helper could check these two flags together,
and include `PRV_M` where the same access rules apply. This is outside
the scope of this patch, but we can look into it once Sdext is merged.
I'll work on it if I have time.


Reviewed-by: Chao Liu <chao.liu@processmission.com>

Thanks,
Chao

> I believe this change is already in line with what we want there, i.e. debug
> mode having at least the same accesses as PRV_M.
> 
> 
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> 
> 
> 
> >           return RISCV_EXCP_NONE;
> >       }
> > 
> 


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

* Re: [PATCH 05/10] monitor/hmp: add CPUClass::get_pc fallback for HMP $pc
  2026-09-30 17:31   ` Philippe Mathieu-Daudé
@ 2026-10-01  4:17     ` Akihiko Odaki
  0 siblings, 0 replies; 25+ messages in thread
From: Akihiko Odaki @ 2026-10-01  4:17 UTC (permalink / raw)
  To: qemu-devel

On 2026/10/01 2:31, Philippe Mathieu-Daudé wrote:
> On 11/9/26 14:27, Marc-André Lureau wrote:
>> Some targets, including x86, have no GDB register named "pc" (x86
>> uses eip/rip). When the GDB register lookup fails for "$pc" in
>> HMP expressions, fall back to CPUClass::get_pc so that "p $pc",
>> "x $pc" etc. work without relying on the legacy MonitorDef table.
>>
>> This prepares for the eventual removal of MonitorDef while making
>> $pc available immediately for all targets that implement get_pc.
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>>   monitor/hmp.c | 8 ++++++--
>>   1 file changed, 6 insertions(+), 2 deletions(-)
> 
> 
>> @@ -435,6 +435,10 @@ static bool gdb_get_register(MonitorHMP *hmp, 
>> int64_t *pval, const char *name)
> 
>> +    if (!strcmp(name, "pc") && cs->cc->get_pc) {
>> +        *pval = cs->cc->get_pc(cs);
>> +        return true;
>> +    }
>>       return false;
>>   }
> Before commit 57206fd42a0 ("more register values in monitor") we had
> $eip (32-bit) aliased as $pc, but I suppose in order to add the 64-bit
> port (see next commit, 75dfaa1e64b "x86-64 port (Jocelyn Mayer)") it
> was unified as a single $pc instead of adding the corresponding $rip:
> 
> -    { "eip|pc", offsetof(CPUState, eip) },
> +    { "pc", 0, monitor_get_pc, },
> 
> This was 22 years ago :) With retrospective I'd say a generic $pc is
> misleading (note, this is only for the x86 architecture, the other
> ones don't suffer from this problem).
> 
> To be pedantic we could add a 'const char *CPUClass::get_pc_regname()'
> helper, but TBH I'd just drop this and let the monitor reports an error.
> gdbstub doesn't suffer from that because EIP/RIP register index are
> used.
> 
> What is the community view on this?

One detail to note is that this patch changes the behavior of $pc in 
32-bit mode.

The new fallback calls x86_cpu_get_pc(), which omits the truncation 
previously performed by the old monitor getter. For example, with a 
32-bit code segment having a base of 0xffff0000 and an EIP of 0x10000, 
execution correctly wraps to address zero, but HMP will report $pc = 
0x100000000. Consequently, `x /1xb $pc` fails while `x /1xb 0` succeeds.

That said, I'm fine with dropping $pc anyway.

Regards,
Akihiko Odaki


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

* Re: [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers
  2026-09-30 17:18 ` Philippe Mathieu-Daudé
@ 2026-10-01  8:00   ` Akihiko Odaki
  2026-10-06 14:31     ` Marc-André Lureau
  0 siblings, 1 reply; 25+ messages in thread
From: Akihiko Odaki @ 2026-10-01  8:00 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, Marc-André Lureau, qemu-devel
  Cc: Dr. David Alan Gilbert, Alex Bennée, Zhao Liu, Peter Maydell,
	Chinmay Rath, Nicholas Piggin, Glenn Miles, Harsh Prateek Bora,
	Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Filippov,
	qemu-arm, qemu-ppc, qemu-riscv, Paolo Bonzini, Laurent Vivier,
	Mark Cave-Ayland, Artyom Tarasenko, Helge Deller,
	Pierrick Bouvier, Warner Losh, Kyle Evans

On 2026/10/01 2:18, Philippe Mathieu-Daudé wrote:
> Cc'ing Akihiko who worked on gdbstub.
> 
> On 11/9/26 14:27, Marc-André Lureau wrote:
>> Hi,
>>
>> HMP monitor supports printing $register expression. The lookup
>> was done via GDB stub registers, and supplementary MonitorDef
>> HMP-specific tables.
>>
>> Migrate HMP registers to use the GDB infrastructure and remove the
>> legacy HMP MonitorDef. Use a "qemu-debug" register group, as they are
>> aliases or synthetic registers, but gdb doesn't seem to care.

Unfortunately, these aliases and synthetic registers appear to have 
several problems:

- GDB already provides writable pseudo-registers for SPARC64's asi and
   pstate. The new QEMU registers shadow them but ignore writes, breaking
   previously supported functionality. See:
  
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/sparc64-tdep.c;h=93db3417a2a9f64790acab33288eb05764112e0b;hb=6a5e5259790e5a854ddbb69eb486b9245fcfeee8#l976

- GDB caches each raw register independently. Updating one alias can
   leave another stale, causing incorrect reads or skipped writes.

- The new raw aliases do not inherit the original registers' unwind
   rules, leading to incorrect register values when selecting older
   call frames.

The latter two issues also affect the RISC-V aliases and cannot be 
resolved merely by changing QEMU's register read/write callbacks. I 
therefore think we need to retain HMP-specific handling for these aliases.

Regards,
Akihiko Odaki

>>
>> Known behavioural changes on RISC-V: CSR lookup is now case-sensitive
>> and vector registers now report "unkown register" instead of a
>> target-specific message ("Unable to print the value of vector vreg 'v0'
>> from this API")
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> Marc-André Lureau (10):
>>        hmp: don't crash on invalid register
>>        gdbstub: fix next register base after register gaps
>>        gdbstub: set feature->base_reg for dynamic features
>>        target/i386: expose segment limits via GDB
>>        monitor/hmp: add CPUClass::get_pc fallback for HMP $pc
>>        target/m68k: expose system registers via GDB
>>        target/sparc64: expose system registers via GDB
>>        target/riscv: bypass smstateen check in debugger mode
>>        target/riscv: expose register aliases via GDB
>>        monitor/hmp: remove legacy MonitorDef infrastructure
>>
>>   configs/targets/i386-softmmu.mak          |   2 +-
>>   configs/targets/m68k-softmmu.mak          |   2 +-
>>   configs/targets/riscv32-linux-user.mak    |   2 +-
>>   configs/targets/riscv32-softmmu.mak       |   2 +-
>>   configs/targets/riscv64-bsd-user.mak      |   2 +-
>>   configs/targets/riscv64-linux-user.mak    |   2 +-
>>   configs/targets/riscv64-softmmu.mak       |   2 +-
>>   configs/targets/sparc64-softmmu.mak       |   2 +-
>>   configs/targets/x86_64-softmmu.mak        |   2 +-
>>   gdbstub/gdb-xml/i386-segments.xml         |  14 +++
>>   gdbstub/gdb-xml/m68k-system.xml           |  32 +++++++
>>   gdbstub/gdb-xml/riscv-32bit-alias.xml     | 105 ++++++++++++++++++++++
>>   gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml |  40 +++++++++
>>   gdbstub/gdb-xml/riscv-64bit-alias.xml     | 105 ++++++++++++++++++++++
>>   gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml |  46 ++++++++++
>>   gdbstub/gdb-xml/sparc64-system.xml        |  22 +++++
>>   gdbstub/gdbstub.c                         |  14 +--
>>   include/hw/core/cpu.h                     |   2 +-
>>   include/hw/core/sysemu-cpu-ops.h          |  16 ----
>>   include/monitor/hmp.h                     |   6 --
>>   include/qemu/typedefs.h                   |   1 -
>>   monitor/hmp.c                             |  52 ++---------
>>   target/arm/gdbstub.c                      |   8 +-
>>   target/arm/gdbstub64.c                    |  10 ++-
>>   target/i386/cpu.c                         |  32 -------
>>   target/i386/gdbstub.c                     |  24 +++++
>>   target/m68k/cpu.c                         |  22 -----
>>   target/m68k/helper.c                      |  47 ++++++++++
>>   target/ppc/gdbstub.c                      |   2 +-
>>   target/riscv/cpu.c                        |   1 -
>>   target/riscv/gdbstub.c                    |  52 ++++++++++-
>>   target/riscv/internals.h                  |   3 -
>>   target/riscv/monitor.c                    | 140 
>> ------------------------------
>>   target/riscv/tcg/csr.c                    |   3 +-
>>   target/sparc/cpu.c                        |  19 ----
>>   target/sparc/gdbstub.c                    |  38 ++++++++
>>   target/xtensa/cpu.c                       |   2 +-
>>   37 files changed, 562 insertions(+), 314 deletions(-)
>> ---
>> base-commit: 209b2afaface001c7d4d981e38f186afe7b24a50
>> change-id: 20260910-query-reg-80cd59cf4707
>>
>> Best regards,
>> -- 
>> Marc-André Lureau <marcandre.lureau@redhat.com>
>>
>>
> 



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

* Re: [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers
  2026-10-01  8:00   ` Akihiko Odaki
@ 2026-10-06 14:31     ` Marc-André Lureau
  2026-10-07  3:08       ` Akihiko Odaki
  0 siblings, 1 reply; 25+ messages in thread
From: Marc-André Lureau @ 2026-10-06 14:31 UTC (permalink / raw)
  To: Akihiko Odaki
  Cc: Philippe Mathieu-Daudé, qemu-devel, Dr. David Alan Gilbert,
	Alex Bennée, Zhao Liu, Peter Maydell, Chinmay Rath,
	Nicholas Piggin, Glenn Miles, Harsh Prateek Bora, Palmer Dabbelt,
	Alistair Francis, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei,
	Chao Liu, Max Filippov, qemu-arm, qemu-ppc, qemu-riscv,
	Paolo Bonzini, Laurent Vivier, Mark Cave-Ayland, Artyom Tarasenko,
	Helge Deller, Pierrick Bouvier, Warner Losh, Kyle Evans

Hi Akihiko

On Thu, Oct 1, 2026 at 12:03 PM Akihiko Odaki
<odaki@rsg.ci.i.u-tokyo.ac.jp> wrote:
>
> On 2026/10/01 2:18, Philippe Mathieu-Daudé wrote:
> > Cc'ing Akihiko who worked on gdbstub.
> >
> > On 11/9/26 14:27, Marc-André Lureau wrote:
> >> Hi,
> >>
> >> HMP monitor supports printing $register expression. The lookup
> >> was done via GDB stub registers, and supplementary MonitorDef
> >> HMP-specific tables.
> >>
> >> Migrate HMP registers to use the GDB infrastructure and remove the
> >> legacy HMP MonitorDef. Use a "qemu-debug" register group, as they are
> >> aliases or synthetic registers, but gdb doesn't seem to care.
>
> Unfortunately, these aliases and synthetic registers appear to have
> several problems:
>
> - GDB already provides writable pseudo-registers for SPARC64's asi and
>    pstate. The new QEMU registers shadow them but ignore writes, breaking
>    previously supported functionality. See:
>
> https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/sparc64-tdep.c;h=93db3417a2a9f64790acab33288eb05764112e0b;hb=6a5e5259790e5a854ddbb69eb486b9245fcfeee8#l976
>
> - GDB caches each raw register independently. Updating one alias can
>    leave another stale, causing incorrect reads or skipped writes.
>
> - The new raw aliases do not inherit the original registers' unwind
>    rules, leading to incorrect register values when selecting older
>    call frames.
>
> The latter two issues also affect the RISC-V aliases and cannot be
> resolved merely by changing QEMU's register read/write callbacks. I
> therefore think we need to retain HMP-specific handling for these aliases.

Thanks for the feedback and findings! Would it be an option to have
qemu/pseudo registers use a prefixed name like "qemu.", then it
shouldn't conflict with GDB. HMP would need to try with it if not
found. Wdyt?

Alternatively, keep the monitor specific register lookup, as a secondary path.

> Regards,
> Akihiko Odaki
>
> >>
> >> Known behavioural changes on RISC-V: CSR lookup is now case-sensitive
> >> and vector registers now report "unkown register" instead of a
> >> target-specific message ("Unable to print the value of vector vreg 'v0'
> >> from this API")
> >>
> >> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> >> ---
> >> Marc-André Lureau (10):
> >>        hmp: don't crash on invalid register
> >>        gdbstub: fix next register base after register gaps
> >>        gdbstub: set feature->base_reg for dynamic features
> >>        target/i386: expose segment limits via GDB
> >>        monitor/hmp: add CPUClass::get_pc fallback for HMP $pc
> >>        target/m68k: expose system registers via GDB
> >>        target/sparc64: expose system registers via GDB
> >>        target/riscv: bypass smstateen check in debugger mode
> >>        target/riscv: expose register aliases via GDB
> >>        monitor/hmp: remove legacy MonitorDef infrastructure
> >>
> >>   configs/targets/i386-softmmu.mak          |   2 +-
> >>   configs/targets/m68k-softmmu.mak          |   2 +-
> >>   configs/targets/riscv32-linux-user.mak    |   2 +-
> >>   configs/targets/riscv32-softmmu.mak       |   2 +-
> >>   configs/targets/riscv64-bsd-user.mak      |   2 +-
> >>   configs/targets/riscv64-linux-user.mak    |   2 +-
> >>   configs/targets/riscv64-softmmu.mak       |   2 +-
> >>   configs/targets/sparc64-softmmu.mak       |   2 +-
> >>   configs/targets/x86_64-softmmu.mak        |   2 +-
> >>   gdbstub/gdb-xml/i386-segments.xml         |  14 +++
> >>   gdbstub/gdb-xml/m68k-system.xml           |  32 +++++++
> >>   gdbstub/gdb-xml/riscv-32bit-alias.xml     | 105 ++++++++++++++++++++++
> >>   gdbstub/gdb-xml/riscv-32bit-fpu-alias.xml |  40 +++++++++
> >>   gdbstub/gdb-xml/riscv-64bit-alias.xml     | 105 ++++++++++++++++++++++
> >>   gdbstub/gdb-xml/riscv-64bit-fpu-alias.xml |  46 ++++++++++
> >>   gdbstub/gdb-xml/sparc64-system.xml        |  22 +++++
> >>   gdbstub/gdbstub.c                         |  14 +--
> >>   include/hw/core/cpu.h                     |   2 +-
> >>   include/hw/core/sysemu-cpu-ops.h          |  16 ----
> >>   include/monitor/hmp.h                     |   6 --
> >>   include/qemu/typedefs.h                   |   1 -
> >>   monitor/hmp.c                             |  52 ++---------
> >>   target/arm/gdbstub.c                      |   8 +-
> >>   target/arm/gdbstub64.c                    |  10 ++-
> >>   target/i386/cpu.c                         |  32 -------
> >>   target/i386/gdbstub.c                     |  24 +++++
> >>   target/m68k/cpu.c                         |  22 -----
> >>   target/m68k/helper.c                      |  47 ++++++++++
> >>   target/ppc/gdbstub.c                      |   2 +-
> >>   target/riscv/cpu.c                        |   1 -
> >>   target/riscv/gdbstub.c                    |  52 ++++++++++-
> >>   target/riscv/internals.h                  |   3 -
> >>   target/riscv/monitor.c                    | 140
> >> ------------------------------
> >>   target/riscv/tcg/csr.c                    |   3 +-
> >>   target/sparc/cpu.c                        |  19 ----
> >>   target/sparc/gdbstub.c                    |  38 ++++++++
> >>   target/xtensa/cpu.c                       |   2 +-
> >>   37 files changed, 562 insertions(+), 314 deletions(-)
> >> ---
> >> base-commit: 209b2afaface001c7d4d981e38f186afe7b24a50
> >> change-id: 20260910-query-reg-80cd59cf4707
> >>
> >> Best regards,
> >> --
> >> Marc-André Lureau <marcandre.lureau@redhat.com>
> >>
> >>
> >
>
>


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

* Re: [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers
  2026-10-06 14:31     ` Marc-André Lureau
@ 2026-10-07  3:08       ` Akihiko Odaki
  0 siblings, 0 replies; 25+ messages in thread
From: Akihiko Odaki @ 2026-10-07  3:08 UTC (permalink / raw)
  To: Marc-André Lureau
  Cc: Philippe Mathieu-Daudé, qemu-devel, Dr. David Alan Gilbert,
	Alex Bennée, Zhao Liu, Peter Maydell, Chinmay Rath,
	Nicholas Piggin, Glenn Miles, Harsh Prateek Bora, Palmer Dabbelt,
	Alistair Francis, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei,
	Chao Liu, Max Filippov, qemu-arm, qemu-ppc, qemu-riscv,
	Paolo Bonzini, Laurent Vivier, Mark Cave-Ayland, Artyom Tarasenko,
	Helge Deller, Pierrick Bouvier, Warner Losh, Kyle Evans

On 2026/10/06 23:31, Marc-André Lureau wrote:
> Hi Akihiko
> 
> On Thu, Oct 1, 2026 at 12:03 PM Akihiko Odaki
> <odaki@rsg.ci.i.u-tokyo.ac.jp> wrote:
>>
>> On 2026/10/01 2:18, Philippe Mathieu-Daudé wrote:
>>> Cc'ing Akihiko who worked on gdbstub.
>>>
>>> On 11/9/26 14:27, Marc-André Lureau wrote:
>>>> Hi,
>>>>
>>>> HMP monitor supports printing $register expression. The lookup
>>>> was done via GDB stub registers, and supplementary MonitorDef
>>>> HMP-specific tables.
>>>>
>>>> Migrate HMP registers to use the GDB infrastructure and remove the
>>>> legacy HMP MonitorDef. Use a "qemu-debug" register group, as they are
>>>> aliases or synthetic registers, but gdb doesn't seem to care.
>>
>> Unfortunately, these aliases and synthetic registers appear to have
>> several problems:
>>
>> - GDB already provides writable pseudo-registers for SPARC64's asi and
>>     pstate. The new QEMU registers shadow them but ignore writes, breaking
>>     previously supported functionality. See:
>>
>> https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/sparc64-tdep.c;h=93db3417a2a9f64790acab33288eb05764112e0b;hb=6a5e5259790e5a854ddbb69eb486b9245fcfeee8#l976
>>
>> - GDB caches each raw register independently. Updating one alias can
>>     leave another stale, causing incorrect reads or skipped writes.
>>
>> - The new raw aliases do not inherit the original registers' unwind
>>     rules, leading to incorrect register values when selecting older
>>     call frames.
>>
>> The latter two issues also affect the RISC-V aliases and cannot be
>> resolved merely by changing QEMU's register read/write callbacks. I
>> therefore think we need to retain HMP-specific handling for these aliases.
> 
> Thanks for the feedback and findings! Would it be an option to have
> qemu/pseudo registers use a prefixed name like "qemu.", then it
> shouldn't conflict with GDB. HMP would need to try with it if not
> found. Wdyt?

That would avoid the conflict, but "info registers" in GDB would then 
list these extra registers. This makes the output noisier, and the 
displayed values could still be misleading or inaccurate.

> 
> Alternatively, keep the monitor specific register lookup, as a secondary path.

Ultimately, the design trade-off comes down to:

- The actual impact of exposing pseudo-registers via gdbstub.
- The relative complexity of implementing pseudo-registers versus
   keeping a monitor-specific lookup as a fallback.

While the issues with pseudo-registers aren't critical, intuitively, 
keeping the monitor-specific lookup as a fallback seems like it wouldn't 
add much complexity, and might even be simpler. If so, I think keeping 
the monitor-specific lookup is the better approach. Otherwise, we may 
need to give this further consideration.

Regards,
Akihiko Odaki


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

end of thread, other threads:[~2026-10-07  8:42 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-11 12:27 [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
2026-09-11 12:27 ` [PATCH 01/10] hmp: don't crash on invalid register Marc-André Lureau
2026-09-30 16:59   ` Philippe Mathieu-Daudé
2026-09-11 12:27 ` [PATCH 02/10] gdbstub: fix next register base after register gaps Marc-André Lureau
2026-09-11 15:29   ` Alex Bennée
2026-09-11 12:27 ` [PATCH 03/10] gdbstub: set feature->base_reg for dynamic features Marc-André Lureau
2026-09-30 17:18   ` Philippe Mathieu-Daudé
2026-09-11 12:27 ` [PATCH 04/10] target/i386: expose segment limits via GDB Marc-André Lureau
2026-09-11 12:27 ` [PATCH 05/10] monitor/hmp: add CPUClass::get_pc fallback for HMP $pc Marc-André Lureau
2026-09-30 17:31   ` Philippe Mathieu-Daudé
2026-10-01  4:17     ` Akihiko Odaki
2026-09-11 12:27 ` [PATCH 06/10] target/m68k: expose system registers via GDB Marc-André Lureau
2026-09-11 12:27 ` [PATCH 07/10] target/sparc64: " Marc-André Lureau
2026-09-11 12:27 ` [PATCH 08/10] target/riscv: bypass smstateen check in debugger mode Marc-André Lureau
2026-09-30 18:24   ` Daniel Henrique Barboza
2026-10-01  0:57     ` Chao Liu via qemu development
2026-10-01  0:57       ` Chao Liu via
2026-10-01  0:57       ` Chao Liu via
2026-09-11 12:27 ` [PATCH 09/10] target/riscv: expose register aliases via GDB Marc-André Lureau
2026-09-11 12:27 ` [PATCH 10/10] monitor/hmp: remove legacy MonitorDef infrastructure Marc-André Lureau
2026-09-30  8:49 ` [PATCH 00/10] monitor/hmp: replace MonitorDef with GDB registers Marc-André Lureau
2026-09-30 17:18 ` Philippe Mathieu-Daudé
2026-10-01  8:00   ` Akihiko Odaki
2026-10-06 14:31     ` Marc-André Lureau
2026-10-07  3:08       ` Akihiko Odaki

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.