diff --git a/include/disas/disas.h b/include/disas/disas.h
index 176775eff7..cd99b0ccd0 100644
--- a/include/disas/disas.h
+++ b/include/disas/disas.h
@@ -5,8 +5,14 @@
 void disas(FILE *out, const void *code, size_t size);
 void target_disas(FILE *out, CPUState *cpu, uint64_t code, size_t size);
 
+typedef enum {
+    MON_DISAS_GVA, /* virtual */
+    MON_DISAS_GPA, /* physical */
+    MON_DISAS_GRA, /* ram_addr_t */
+} MonitorDisasSpace;
+
 void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc,
-                   int nb_insn, bool is_physical);
+                   int nb_insn, MonitorDisasSpace space);
 
 char *plugin_disas(CPUState *cpu, uint64_t addr, size_t size);
 
diff --git a/disas/disas-mon.c b/disas/disas-mon.c
index 48ac492c6c..d486f64c92 100644
--- a/disas/disas-mon.c
+++ b/disas/disas-mon.c
@@ -23,9 +23,27 @@ physical_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length,
     return res == MEMTX_OK ? 0 : EIO;
 }
 
+static int
+ram_addr_read_memory(bfd_vma memaddr, bfd_byte *myaddr, int length,
+                     struct disassemble_info *info)
+{
+    hwaddr hw_length;
+    void *p;
+
+    RCU_READ_LOCK_GUARD();
+
+    hw_length = length;
+    p = qemu_ram_ptr_length(NULL, memaddr, &hw_length, false);
+    if (hw_length < length) {
+        return EIO;
+    }
+    memcpy(myaddr, p, length);
+    return 0;
+}
+
 /* Disassembler for the monitor.  */
 void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc,
-                   int nb_insn, bool is_physical)
+                   int nb_insn, MonitorDisasSpace space)
 {
     int count, i;
     CPUDebug s;
@@ -35,8 +53,18 @@ void monitor_disas(Monitor *mon, CPUState *cpu, uint64_t pc,
     s.info.fprintf_func = disas_gstring_printf;
     s.info.stream = (FILE *)ds;  /* abuse this slot */
 
-    if (is_physical) {
+    switch (space) {
+    case MON_DISAS_GVA:
+        /* target_read_memory set in disas_initialize_debug_target */
+        break;
+    case MON_DISAS_GPA:
         s.info.read_memory_func = physical_read_memory;
+        break;
+    case MON_DISAS_GRA:
+        s.info.read_memory_func = ram_addr_read_memory;
+        break;
+    default:
+        g_assert_not_reached();
     }
     s.info.buffer_vma = pc;
 
diff --git a/monitor/hmp-cmds-target.c b/monitor/hmp-cmds-target.c
index d9fbcac08d..476cf68e81 100644
--- a/monitor/hmp-cmds-target.c
+++ b/monitor/hmp-cmds-target.c
@@ -120,21 +120,20 @@ void hmp_info_registers(Monitor *mon, const QDict *qdict)
 }
 
 static void memory_dump(Monitor *mon, int count, int format, int wsize,
-                        hwaddr addr, int is_physical)
+                        hwaddr addr, MonitorDisasSpace space)
 {
     int l, line_size, i, max_digits, len;
     uint8_t buf[16];
     uint64_t v;
     CPUState *cs = mon_get_cpu(mon);
 
-    if (!cs && (format == 'i' || !is_physical)) {
+    if (space == MON_DISAS_GVA || format == 'i') {
         monitor_printf(mon, "Can not dump without CPU\n");
         return;
     }
 
     if (format == 'i') {
-        monitor_disas(mon, cs, addr, count, is_physical);
-        return;
+        monitor_disas(mon, cs, addr, count, space);
     }
 
     len = wsize * count;
@@ -163,15 +162,21 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
     }
 
     while (len > 0) {
-        if (is_physical) {
-            monitor_printf(mon, HWADDR_FMT_plx ":", addr);
-        } else {
+        switch (space) {
+        case MON_DISAS_GVA:
             monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr);
+            break;
+        case MON_DISAS_GPA:
+            monitor_printf(mon, HWADDR_FMT_plx ":", addr);
+            break;
+        default:
+            g_assert_not_reached();
         }
         l = len;
-        if (l > line_size)
+        if (l > line_size) {
             l = line_size;
-        if (is_physical) {
+        }
+        if (space == MON_DISAS_GPA) {
             AddressSpace *as = cs ? cs->as : &address_space_memory;
             MemTxResult r = address_space_read(as, addr,
                                                MEMTXATTRS_UNSPECIFIED, buf, l);
@@ -235,7 +240,7 @@ void hmp_memory_dump(Monitor *mon, const QDict *qdict)
     int size = qdict_get_int(qdict, "size");
     target_long addr = qdict_get_int(qdict, "addr");
 
-    memory_dump(mon, count, format, size, addr, 0);
+    memory_dump(mon, count, format, size, addr, MON_DISAS_GVA);
 }
 
 void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
@@ -245,7 +250,7 @@ void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
     int size = qdict_get_int(qdict, "size");
     hwaddr addr = qdict_get_int(qdict, "addr");
 
-    memory_dump(mon, count, format, size, addr, 1);
+    memory_dump(mon, count, format, size, addr, MON_DISAS_GPA);
 }
 
 void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp)
