xref: /qemu/monitor/hmp-cmds-target.c (revision b77af26e)
1e2245566SMarkus Armbruster /*
2e2245566SMarkus Armbruster  * Miscellaneous target-dependent HMP commands
3e2245566SMarkus Armbruster  *
4e2245566SMarkus Armbruster  * Copyright (c) 2003-2004 Fabrice Bellard
5e2245566SMarkus Armbruster  *
6e2245566SMarkus Armbruster  * Permission is hereby granted, free of charge, to any person obtaining a copy
7e2245566SMarkus Armbruster  * of this software and associated documentation files (the "Software"), to deal
8e2245566SMarkus Armbruster  * in the Software without restriction, including without limitation the rights
9e2245566SMarkus Armbruster  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10e2245566SMarkus Armbruster  * copies of the Software, and to permit persons to whom the Software is
11e2245566SMarkus Armbruster  * furnished to do so, subject to the following conditions:
12e2245566SMarkus Armbruster  *
13e2245566SMarkus Armbruster  * The above copyright notice and this permission notice shall be included in
14e2245566SMarkus Armbruster  * all copies or substantial portions of the Software.
15e2245566SMarkus Armbruster  *
16e2245566SMarkus Armbruster  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17e2245566SMarkus Armbruster  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18e2245566SMarkus Armbruster  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19e2245566SMarkus Armbruster  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20e2245566SMarkus Armbruster  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21e2245566SMarkus Armbruster  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22e2245566SMarkus Armbruster  * THE SOFTWARE.
23e2245566SMarkus Armbruster  */
24e2245566SMarkus Armbruster 
25e2245566SMarkus Armbruster #include "qemu/osdep.h"
26e2245566SMarkus Armbruster #include "disas/disas.h"
27e2245566SMarkus Armbruster #include "exec/address-spaces.h"
28e2245566SMarkus Armbruster #include "monitor/hmp-target.h"
29e2245566SMarkus Armbruster #include "monitor/monitor-internal.h"
30e2245566SMarkus Armbruster #include "qapi/error.h"
31e2245566SMarkus Armbruster #include "qapi/qmp/qdict.h"
32e2245566SMarkus Armbruster #include "sysemu/hw_accel.h"
33e2245566SMarkus Armbruster 
34e2245566SMarkus Armbruster /* Set the current CPU defined by the user. Callers must hold BQL. */
35e2245566SMarkus Armbruster int monitor_set_cpu(Monitor *mon, int cpu_index)
36e2245566SMarkus Armbruster {
37e2245566SMarkus Armbruster     CPUState *cpu;
38e2245566SMarkus Armbruster 
39e2245566SMarkus Armbruster     cpu = qemu_get_cpu(cpu_index);
40e2245566SMarkus Armbruster     if (cpu == NULL) {
41e2245566SMarkus Armbruster         return -1;
42e2245566SMarkus Armbruster     }
43e2245566SMarkus Armbruster     g_free(mon->mon_cpu_path);
44e2245566SMarkus Armbruster     mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
45e2245566SMarkus Armbruster     return 0;
46e2245566SMarkus Armbruster }
47e2245566SMarkus Armbruster 
48e2245566SMarkus Armbruster /* Callers must hold BQL. */
49e2245566SMarkus Armbruster static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize)
50e2245566SMarkus Armbruster {
51e2245566SMarkus Armbruster     CPUState *cpu = NULL;
52e2245566SMarkus Armbruster 
53e2245566SMarkus Armbruster     if (mon->mon_cpu_path) {
54e2245566SMarkus Armbruster         cpu = (CPUState *) object_resolve_path_type(mon->mon_cpu_path,
55e2245566SMarkus Armbruster                                                     TYPE_CPU, NULL);
56e2245566SMarkus Armbruster         if (!cpu) {
57e2245566SMarkus Armbruster             g_free(mon->mon_cpu_path);
58e2245566SMarkus Armbruster             mon->mon_cpu_path = NULL;
59e2245566SMarkus Armbruster         }
60e2245566SMarkus Armbruster     }
61e2245566SMarkus Armbruster     if (!mon->mon_cpu_path) {
62e2245566SMarkus Armbruster         if (!first_cpu) {
63e2245566SMarkus Armbruster             return NULL;
64e2245566SMarkus Armbruster         }
65e2245566SMarkus Armbruster         monitor_set_cpu(mon, first_cpu->cpu_index);
66e2245566SMarkus Armbruster         cpu = first_cpu;
67e2245566SMarkus Armbruster     }
68e2245566SMarkus Armbruster     assert(cpu != NULL);
69e2245566SMarkus Armbruster     if (synchronize) {
70e2245566SMarkus Armbruster         cpu_synchronize_state(cpu);
71e2245566SMarkus Armbruster     }
72e2245566SMarkus Armbruster     return cpu;
73e2245566SMarkus Armbruster }
74e2245566SMarkus Armbruster 
75e2245566SMarkus Armbruster CPUState *mon_get_cpu(Monitor *mon)
76e2245566SMarkus Armbruster {
77e2245566SMarkus Armbruster     return mon_get_cpu_sync(mon, true);
78e2245566SMarkus Armbruster }
79e2245566SMarkus Armbruster 
80e2245566SMarkus Armbruster CPUArchState *mon_get_cpu_env(Monitor *mon)
81e2245566SMarkus Armbruster {
82e2245566SMarkus Armbruster     CPUState *cs = mon_get_cpu(mon);
83e2245566SMarkus Armbruster 
84b77af26eSRichard Henderson     return cs ? cpu_env(cs) : NULL;
85e2245566SMarkus Armbruster }
86e2245566SMarkus Armbruster 
87e2245566SMarkus Armbruster int monitor_get_cpu_index(Monitor *mon)
88e2245566SMarkus Armbruster {
89e2245566SMarkus Armbruster     CPUState *cs = mon_get_cpu_sync(mon, false);
90e2245566SMarkus Armbruster 
91e2245566SMarkus Armbruster     return cs ? cs->cpu_index : UNASSIGNED_CPU_INDEX;
92e2245566SMarkus Armbruster }
93e2245566SMarkus Armbruster 
94e2245566SMarkus Armbruster void hmp_info_registers(Monitor *mon, const QDict *qdict)
95e2245566SMarkus Armbruster {
96e2245566SMarkus Armbruster     bool all_cpus = qdict_get_try_bool(qdict, "cpustate_all", false);
97e2245566SMarkus Armbruster     int vcpu = qdict_get_try_int(qdict, "vcpu", -1);
98e2245566SMarkus Armbruster     CPUState *cs;
99e2245566SMarkus Armbruster 
100e2245566SMarkus Armbruster     if (all_cpus) {
101e2245566SMarkus Armbruster         CPU_FOREACH(cs) {
102e2245566SMarkus Armbruster             monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
103e2245566SMarkus Armbruster             cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
104e2245566SMarkus Armbruster         }
105e2245566SMarkus Armbruster     } else {
106e2245566SMarkus Armbruster         cs = vcpu >= 0 ? qemu_get_cpu(vcpu) : mon_get_cpu(mon);
107e2245566SMarkus Armbruster 
108e2245566SMarkus Armbruster         if (!cs) {
109e2245566SMarkus Armbruster             if (vcpu >= 0) {
110e2245566SMarkus Armbruster                 monitor_printf(mon, "CPU#%d not available\n", vcpu);
111e2245566SMarkus Armbruster             } else {
112e2245566SMarkus Armbruster                 monitor_printf(mon, "No CPU available\n");
113e2245566SMarkus Armbruster             }
114e2245566SMarkus Armbruster             return;
115e2245566SMarkus Armbruster         }
116e2245566SMarkus Armbruster 
117e2245566SMarkus Armbruster         monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
118e2245566SMarkus Armbruster         cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
119e2245566SMarkus Armbruster     }
120e2245566SMarkus Armbruster }
121e2245566SMarkus Armbruster 
122e2245566SMarkus Armbruster static void memory_dump(Monitor *mon, int count, int format, int wsize,
123e2245566SMarkus Armbruster                         hwaddr addr, int is_physical)
124e2245566SMarkus Armbruster {
125e2245566SMarkus Armbruster     int l, line_size, i, max_digits, len;
126e2245566SMarkus Armbruster     uint8_t buf[16];
127e2245566SMarkus Armbruster     uint64_t v;
128e2245566SMarkus Armbruster     CPUState *cs = mon_get_cpu(mon);
129e2245566SMarkus Armbruster 
130e2245566SMarkus Armbruster     if (!cs && (format == 'i' || !is_physical)) {
131e2245566SMarkus Armbruster         monitor_printf(mon, "Can not dump without CPU\n");
132e2245566SMarkus Armbruster         return;
133e2245566SMarkus Armbruster     }
134e2245566SMarkus Armbruster 
135e2245566SMarkus Armbruster     if (format == 'i') {
136e2245566SMarkus Armbruster         monitor_disas(mon, cs, addr, count, is_physical);
137e2245566SMarkus Armbruster         return;
138e2245566SMarkus Armbruster     }
139e2245566SMarkus Armbruster 
140e2245566SMarkus Armbruster     len = wsize * count;
141e2245566SMarkus Armbruster     if (wsize == 1) {
142e2245566SMarkus Armbruster         line_size = 8;
143e2245566SMarkus Armbruster     } else {
144e2245566SMarkus Armbruster         line_size = 16;
145e2245566SMarkus Armbruster     }
146e2245566SMarkus Armbruster     max_digits = 0;
147e2245566SMarkus Armbruster 
148e2245566SMarkus Armbruster     switch(format) {
149e2245566SMarkus Armbruster     case 'o':
150e2245566SMarkus Armbruster         max_digits = DIV_ROUND_UP(wsize * 8, 3);
151e2245566SMarkus Armbruster         break;
152e2245566SMarkus Armbruster     default:
153e2245566SMarkus Armbruster     case 'x':
154e2245566SMarkus Armbruster         max_digits = (wsize * 8) / 4;
155e2245566SMarkus Armbruster         break;
156e2245566SMarkus Armbruster     case 'u':
157e2245566SMarkus Armbruster     case 'd':
158e2245566SMarkus Armbruster         max_digits = DIV_ROUND_UP(wsize * 8 * 10, 33);
159e2245566SMarkus Armbruster         break;
160e2245566SMarkus Armbruster     case 'c':
161e2245566SMarkus Armbruster         wsize = 1;
162e2245566SMarkus Armbruster         break;
163e2245566SMarkus Armbruster     }
164e2245566SMarkus Armbruster 
165e2245566SMarkus Armbruster     while (len > 0) {
166e2245566SMarkus Armbruster         if (is_physical) {
167e2245566SMarkus Armbruster             monitor_printf(mon, HWADDR_FMT_plx ":", addr);
168e2245566SMarkus Armbruster         } else {
169e2245566SMarkus Armbruster             monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr);
170e2245566SMarkus Armbruster         }
171e2245566SMarkus Armbruster         l = len;
172e2245566SMarkus Armbruster         if (l > line_size)
173e2245566SMarkus Armbruster             l = line_size;
174e2245566SMarkus Armbruster         if (is_physical) {
175e2245566SMarkus Armbruster             AddressSpace *as = cs ? cs->as : &address_space_memory;
176e2245566SMarkus Armbruster             MemTxResult r = address_space_read(as, addr,
177e2245566SMarkus Armbruster                                                MEMTXATTRS_UNSPECIFIED, buf, l);
178e2245566SMarkus Armbruster             if (r != MEMTX_OK) {
179e2245566SMarkus Armbruster                 monitor_printf(mon, " Cannot access memory\n");
180e2245566SMarkus Armbruster                 break;
181e2245566SMarkus Armbruster             }
182e2245566SMarkus Armbruster         } else {
183e2245566SMarkus Armbruster             if (cpu_memory_rw_debug(cs, addr, buf, l, 0) < 0) {
184e2245566SMarkus Armbruster                 monitor_printf(mon, " Cannot access memory\n");
185e2245566SMarkus Armbruster                 break;
186e2245566SMarkus Armbruster             }
187e2245566SMarkus Armbruster         }
188e2245566SMarkus Armbruster         i = 0;
189e2245566SMarkus Armbruster         while (i < l) {
190e2245566SMarkus Armbruster             switch(wsize) {
191e2245566SMarkus Armbruster             default:
192e2245566SMarkus Armbruster             case 1:
193e2245566SMarkus Armbruster                 v = ldub_p(buf + i);
194e2245566SMarkus Armbruster                 break;
195e2245566SMarkus Armbruster             case 2:
196e2245566SMarkus Armbruster                 v = lduw_p(buf + i);
197e2245566SMarkus Armbruster                 break;
198e2245566SMarkus Armbruster             case 4:
199e2245566SMarkus Armbruster                 v = (uint32_t)ldl_p(buf + i);
200e2245566SMarkus Armbruster                 break;
201e2245566SMarkus Armbruster             case 8:
202e2245566SMarkus Armbruster                 v = ldq_p(buf + i);
203e2245566SMarkus Armbruster                 break;
204e2245566SMarkus Armbruster             }
205e2245566SMarkus Armbruster             monitor_printf(mon, " ");
206e2245566SMarkus Armbruster             switch(format) {
207e2245566SMarkus Armbruster             case 'o':
208e2245566SMarkus Armbruster                 monitor_printf(mon, "%#*" PRIo64, max_digits, v);
209e2245566SMarkus Armbruster                 break;
210e2245566SMarkus Armbruster             case 'x':
211e2245566SMarkus Armbruster                 monitor_printf(mon, "0x%0*" PRIx64, max_digits, v);
212e2245566SMarkus Armbruster                 break;
213e2245566SMarkus Armbruster             case 'u':
214e2245566SMarkus Armbruster                 monitor_printf(mon, "%*" PRIu64, max_digits, v);
215e2245566SMarkus Armbruster                 break;
216e2245566SMarkus Armbruster             case 'd':
217e2245566SMarkus Armbruster                 monitor_printf(mon, "%*" PRId64, max_digits, v);
218e2245566SMarkus Armbruster                 break;
219e2245566SMarkus Armbruster             case 'c':
220e2245566SMarkus Armbruster                 monitor_printc(mon, v);
221e2245566SMarkus Armbruster                 break;
222e2245566SMarkus Armbruster             }
223e2245566SMarkus Armbruster             i += wsize;
224e2245566SMarkus Armbruster         }
225e2245566SMarkus Armbruster         monitor_printf(mon, "\n");
226e2245566SMarkus Armbruster         addr += l;
227e2245566SMarkus Armbruster         len -= l;
228e2245566SMarkus Armbruster     }
229e2245566SMarkus Armbruster }
230e2245566SMarkus Armbruster 
231e2245566SMarkus Armbruster void hmp_memory_dump(Monitor *mon, const QDict *qdict)
232e2245566SMarkus Armbruster {
233e2245566SMarkus Armbruster     int count = qdict_get_int(qdict, "count");
234e2245566SMarkus Armbruster     int format = qdict_get_int(qdict, "format");
235e2245566SMarkus Armbruster     int size = qdict_get_int(qdict, "size");
236e2245566SMarkus Armbruster     target_long addr = qdict_get_int(qdict, "addr");
237e2245566SMarkus Armbruster 
238e2245566SMarkus Armbruster     memory_dump(mon, count, format, size, addr, 0);
239e2245566SMarkus Armbruster }
240e2245566SMarkus Armbruster 
241e2245566SMarkus Armbruster void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
242e2245566SMarkus Armbruster {
243e2245566SMarkus Armbruster     int count = qdict_get_int(qdict, "count");
244e2245566SMarkus Armbruster     int format = qdict_get_int(qdict, "format");
245e2245566SMarkus Armbruster     int size = qdict_get_int(qdict, "size");
246e2245566SMarkus Armbruster     hwaddr addr = qdict_get_int(qdict, "addr");
247e2245566SMarkus Armbruster 
248e2245566SMarkus Armbruster     memory_dump(mon, count, format, size, addr, 1);
249e2245566SMarkus Armbruster }
250e2245566SMarkus Armbruster 
251e2245566SMarkus Armbruster void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp)
252e2245566SMarkus Armbruster {
253e2245566SMarkus Armbruster     Int128 gpa_region_size;
254e2245566SMarkus Armbruster     MemoryRegionSection mrs = memory_region_find(get_system_memory(),
255e2245566SMarkus Armbruster                                                  addr, size);
256e2245566SMarkus Armbruster 
257e2245566SMarkus Armbruster     if (!mrs.mr) {
258e2245566SMarkus Armbruster         error_setg(errp, "No memory is mapped at address 0x%" HWADDR_PRIx, addr);
259e2245566SMarkus Armbruster         return NULL;
260e2245566SMarkus Armbruster     }
261e2245566SMarkus Armbruster 
262e2245566SMarkus Armbruster     if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) {
263e2245566SMarkus Armbruster         error_setg(errp, "Memory at address 0x%" HWADDR_PRIx "is not RAM", addr);
264e2245566SMarkus Armbruster         memory_region_unref(mrs.mr);
265e2245566SMarkus Armbruster         return NULL;
266e2245566SMarkus Armbruster     }
267e2245566SMarkus Armbruster 
268e2245566SMarkus Armbruster     gpa_region_size = int128_make64(size);
269e2245566SMarkus Armbruster     if (int128_lt(mrs.size, gpa_region_size)) {
270e2245566SMarkus Armbruster         error_setg(errp, "Size of memory region at 0x%" HWADDR_PRIx
271e2245566SMarkus Armbruster                    " exceeded.", addr);
272e2245566SMarkus Armbruster         memory_region_unref(mrs.mr);
273e2245566SMarkus Armbruster         return NULL;
274e2245566SMarkus Armbruster     }
275e2245566SMarkus Armbruster 
276e2245566SMarkus Armbruster     *p_mr = mrs.mr;
277e2245566SMarkus Armbruster     return qemu_map_ram_ptr(mrs.mr->ram_block, mrs.offset_within_region);
278e2245566SMarkus Armbruster }
279e2245566SMarkus Armbruster 
280e2245566SMarkus Armbruster void hmp_gpa2hva(Monitor *mon, const QDict *qdict)
281e2245566SMarkus Armbruster {
282e2245566SMarkus Armbruster     hwaddr addr = qdict_get_int(qdict, "addr");
283e2245566SMarkus Armbruster     Error *local_err = NULL;
284e2245566SMarkus Armbruster     MemoryRegion *mr = NULL;
285e2245566SMarkus Armbruster     void *ptr;
286e2245566SMarkus Armbruster 
287e2245566SMarkus Armbruster     ptr = gpa2hva(&mr, addr, 1, &local_err);
288e2245566SMarkus Armbruster     if (local_err) {
289e2245566SMarkus Armbruster         error_report_err(local_err);
290e2245566SMarkus Armbruster         return;
291e2245566SMarkus Armbruster     }
292e2245566SMarkus Armbruster 
293e2245566SMarkus Armbruster     monitor_printf(mon, "Host virtual address for 0x%" HWADDR_PRIx
294e2245566SMarkus Armbruster                    " (%s) is %p\n",
295e2245566SMarkus Armbruster                    addr, mr->name, ptr);
296e2245566SMarkus Armbruster 
297e2245566SMarkus Armbruster     memory_region_unref(mr);
298e2245566SMarkus Armbruster }
299e2245566SMarkus Armbruster 
300e2245566SMarkus Armbruster void hmp_gva2gpa(Monitor *mon, const QDict *qdict)
301e2245566SMarkus Armbruster {
302e2245566SMarkus Armbruster     target_ulong addr = qdict_get_int(qdict, "addr");
303e2245566SMarkus Armbruster     MemTxAttrs attrs;
304e2245566SMarkus Armbruster     CPUState *cs = mon_get_cpu(mon);
305e2245566SMarkus Armbruster     hwaddr gpa;
306e2245566SMarkus Armbruster 
307e2245566SMarkus Armbruster     if (!cs) {
308e2245566SMarkus Armbruster         monitor_printf(mon, "No cpu\n");
309e2245566SMarkus Armbruster         return;
310e2245566SMarkus Armbruster     }
311e2245566SMarkus Armbruster 
312e2245566SMarkus Armbruster     gpa  = cpu_get_phys_page_attrs_debug(cs, addr & TARGET_PAGE_MASK, &attrs);
313e2245566SMarkus Armbruster     if (gpa == -1) {
314e2245566SMarkus Armbruster         monitor_printf(mon, "Unmapped\n");
315e2245566SMarkus Armbruster     } else {
316e2245566SMarkus Armbruster         monitor_printf(mon, "gpa: %#" HWADDR_PRIx "\n",
317e2245566SMarkus Armbruster                        gpa + (addr & ~TARGET_PAGE_MASK));
318e2245566SMarkus Armbruster     }
319e2245566SMarkus Armbruster }
320e2245566SMarkus Armbruster 
321e2245566SMarkus Armbruster #ifdef CONFIG_LINUX
322e2245566SMarkus Armbruster static uint64_t vtop(void *ptr, Error **errp)
323e2245566SMarkus Armbruster {
324e2245566SMarkus Armbruster     uint64_t pinfo;
325e2245566SMarkus Armbruster     uint64_t ret = -1;
326e2245566SMarkus Armbruster     uintptr_t addr = (uintptr_t) ptr;
327e2245566SMarkus Armbruster     uintptr_t pagesize = qemu_real_host_page_size();
328e2245566SMarkus Armbruster     off_t offset = addr / pagesize * sizeof(pinfo);
329e2245566SMarkus Armbruster     int fd;
330e2245566SMarkus Armbruster 
331e2245566SMarkus Armbruster     fd = open("/proc/self/pagemap", O_RDONLY);
332e2245566SMarkus Armbruster     if (fd == -1) {
333e2245566SMarkus Armbruster         error_setg_errno(errp, errno, "Cannot open /proc/self/pagemap");
334e2245566SMarkus Armbruster         return -1;
335e2245566SMarkus Armbruster     }
336e2245566SMarkus Armbruster 
337e2245566SMarkus Armbruster     /* Force copy-on-write if necessary.  */
338e2245566SMarkus Armbruster     qatomic_add((uint8_t *)ptr, 0);
339e2245566SMarkus Armbruster 
340e2245566SMarkus Armbruster     if (pread(fd, &pinfo, sizeof(pinfo), offset) != sizeof(pinfo)) {
341e2245566SMarkus Armbruster         error_setg_errno(errp, errno, "Cannot read pagemap");
342e2245566SMarkus Armbruster         goto out;
343e2245566SMarkus Armbruster     }
344e2245566SMarkus Armbruster     if ((pinfo & (1ull << 63)) == 0) {
345e2245566SMarkus Armbruster         error_setg(errp, "Page not present");
346e2245566SMarkus Armbruster         goto out;
347e2245566SMarkus Armbruster     }
348e2245566SMarkus Armbruster     ret = ((pinfo & 0x007fffffffffffffull) * pagesize) | (addr & (pagesize - 1));
349e2245566SMarkus Armbruster 
350e2245566SMarkus Armbruster out:
351e2245566SMarkus Armbruster     close(fd);
352e2245566SMarkus Armbruster     return ret;
353e2245566SMarkus Armbruster }
354e2245566SMarkus Armbruster 
355e2245566SMarkus Armbruster void hmp_gpa2hpa(Monitor *mon, const QDict *qdict)
356e2245566SMarkus Armbruster {
357e2245566SMarkus Armbruster     hwaddr addr = qdict_get_int(qdict, "addr");
358e2245566SMarkus Armbruster     Error *local_err = NULL;
359e2245566SMarkus Armbruster     MemoryRegion *mr = NULL;
360e2245566SMarkus Armbruster     void *ptr;
361e2245566SMarkus Armbruster     uint64_t physaddr;
362e2245566SMarkus Armbruster 
363e2245566SMarkus Armbruster     ptr = gpa2hva(&mr, addr, 1, &local_err);
364e2245566SMarkus Armbruster     if (local_err) {
365e2245566SMarkus Armbruster         error_report_err(local_err);
366e2245566SMarkus Armbruster         return;
367e2245566SMarkus Armbruster     }
368e2245566SMarkus Armbruster 
369e2245566SMarkus Armbruster     physaddr = vtop(ptr, &local_err);
370e2245566SMarkus Armbruster     if (local_err) {
371e2245566SMarkus Armbruster         error_report_err(local_err);
372e2245566SMarkus Armbruster     } else {
373e2245566SMarkus Armbruster         monitor_printf(mon, "Host physical address for 0x%" HWADDR_PRIx
374e2245566SMarkus Armbruster                        " (%s) is 0x%" PRIx64 "\n",
375e2245566SMarkus Armbruster                        addr, mr->name, (uint64_t) physaddr);
376e2245566SMarkus Armbruster     }
377e2245566SMarkus Armbruster 
378e2245566SMarkus Armbruster     memory_region_unref(mr);
379e2245566SMarkus Armbruster }
380e2245566SMarkus Armbruster #endif
381