diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 55d50c42c6..b0f35e6829 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -249,9 +249,9 @@ ETEXI { .name = "mtree", - .args_type = "", - .params = "", - .help = "show memory tree", + .args_type = "flatview:-f", + .params = "[-f]", + .help = "show memory tree (-f: dump flat view for address spaces)", .cmd = hmp_info_mtree, }, diff --git a/include/exec/memory.h b/include/exec/memory.h index a10044f08f..987f9251c6 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1250,7 +1250,7 @@ void memory_global_dirty_log_start(void); */ void memory_global_dirty_log_stop(void); -void mtree_info(fprintf_function mon_printf, void *f); +void mtree_info(fprintf_function mon_printf, void *f, bool flatview); /** * memory_region_dispatch_read: perform a read directly to the specified diff --git a/memory.c b/memory.c index c42bde4041..6498727552 100644 --- a/memory.c +++ b/memory.c @@ -2564,12 +2564,51 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f, } } -void mtree_info(fprintf_function mon_printf, void *f) +static void mtree_print_flatview(fprintf_function p, void *f, + AddressSpace *as) +{ + FlatView *view = address_space_get_flatview(as); + FlatRange *range = &view->ranges[0]; + MemoryRegion *mr; + int n = view->nr; + + if (n <= 0) { + p(f, MTREE_INDENT "No rendered FlatView for " + "address space '%s'\n", as->name); + flatview_unref(view); + return; + } + + while (n--) { + mr = range->mr; + p(f, MTREE_INDENT TARGET_FMT_plx "-" + TARGET_FMT_plx " (prio %d, %s): %s\n", + int128_get64(range->addr.start), + int128_get64(range->addr.start) + MR_SIZE(range->addr.size), + mr->priority, + memory_region_type(mr), + memory_region_name(mr)); + range++; + } + + flatview_unref(view); +} + +void mtree_info(fprintf_function mon_printf, void *f, bool flatview) { MemoryRegionListHead ml_head; MemoryRegionList *ml, *ml2; AddressSpace *as; + if (flatview) { + QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { + mon_printf(f, "address-space (flat view): %s\n", as->name); + mtree_print_flatview(mon_printf, f, as); + mon_printf(f, "\n"); + } + return; + } + QTAILQ_INIT(&ml_head); QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) { diff --git a/monitor.c b/monitor.c index 8b06b63729..6ac4e95ef7 100644 --- a/monitor.c +++ b/monitor.c @@ -1529,7 +1529,9 @@ static void hmp_boot_set(Monitor *mon, const QDict *qdict) static void hmp_info_mtree(Monitor *mon, const QDict *qdict) { - mtree_info((fprintf_function)monitor_printf, mon); + bool flatview = qdict_get_try_bool(qdict, "flatview", false); + + mtree_info((fprintf_function)monitor_printf, mon, flatview); } static void hmp_info_numa(Monitor *mon, const QDict *qdict)