This is very handy when debugging a guest, especially when it's stuck on accessing some HW and the only way to figure out what specific piece of HW is to translate the virtual address to a hardware address that can then be matched with the mtree
Signed-off-by: Benjamin Herrenschmidt <b...@kernel.crashing.org> --- hmp-commands.hx | 15 +++++++++++++++ monitor.c | 11 +++++++++++ 2 files changed, 26 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 848efee..2d0ce4e 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -569,6 +569,21 @@ Write to I/O port. ETEXI { + .name = "xlate", + .args_type = "addr:l", + .params = "addr", + .help = "Translate virtual address via the MMU", + .mhandler.cmd = hmp_mmu_xlate, + }, + +STEXI +@item xlate @var{addr} +@findex xlate +Translate virtual address + +ETEXI + + { .name = "sendkey", .args_type = "keys:s,hold-time:i?", .params = "keys [hold_ms]", diff --git a/monitor.c b/monitor.c index 5d68a5d..b2b3a6e 100644 --- a/monitor.c +++ b/monitor.c @@ -1505,6 +1505,17 @@ static void hmp_ioport_write(Monitor *mon, const QDict *qdict) } } +static void hmp_mmu_xlate(Monitor *mon, const QDict *qdict) +{ + CPUState *cpu = mon_get_cpu(); + vaddr va = qdict_get_int(qdict, "addr"); + hwaddr pa; + + pa = cpu_get_phys_page_debug(cpu, va); + pa |= (va & ~TARGET_PAGE_MASK); + monitor_printf(mon, "0x%#" HWADDR_PRIx "\n", pa); +} + static void hmp_boot_set(Monitor *mon, const QDict *qdict) { Error *local_err = NULL;