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