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