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 "exec/address-spaces.h" 28 #include "exec/memory.h" 29 #include "monitor/hmp-target.h" 30 #include "monitor/monitor-internal.h" 31 #include "qapi/error.h" 32 #include "qapi/qmp/qdict.h" 33 #include "sysemu/hw_accel.h" 34 35 /* Set the current CPU defined by the user. Callers must hold BQL. */ 36 int monitor_set_cpu(Monitor *mon, int cpu_index) 37 { 38 CPUState *cpu; 39 40 cpu = qemu_get_cpu(cpu_index); 41 if (cpu == NULL) { 42 return -1; 43 } 44 g_free(mon->mon_cpu_path); 45 mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu)); 46 return 0; 47 } 48 49 /* Callers must hold BQL. */ 50 static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize) 51 { 52 CPUState *cpu = NULL; 53 54 if (mon->mon_cpu_path) { 55 cpu = (CPUState *) object_resolve_path_type(mon->mon_cpu_path, 56 TYPE_CPU, NULL); 57 if (!cpu) { 58 g_free(mon->mon_cpu_path); 59 mon->mon_cpu_path = NULL; 60 } 61 } 62 if (!mon->mon_cpu_path) { 63 if (!first_cpu) { 64 return NULL; 65 } 66 monitor_set_cpu(mon, first_cpu->cpu_index); 67 cpu = first_cpu; 68 } 69 assert(cpu != NULL); 70 if (synchronize) { 71 cpu_synchronize_state(cpu); 72 } 73 return cpu; 74 } 75 76 CPUState *mon_get_cpu(Monitor *mon) 77 { 78 return mon_get_cpu_sync(mon, true); 79 } 80 81 CPUArchState *mon_get_cpu_env(Monitor *mon) 82 { 83 CPUState *cs = mon_get_cpu(mon); 84 85 return cs ? cpu_env(cs) : NULL; 86 } 87 88 int monitor_get_cpu_index(Monitor *mon) 89 { 90 CPUState *cs = mon_get_cpu_sync(mon, false); 91 92 return cs ? cs->cpu_index : UNASSIGNED_CPU_INDEX; 93 } 94 95 void hmp_info_registers(Monitor *mon, const QDict *qdict) 96 { 97 bool all_cpus = qdict_get_try_bool(qdict, "cpustate_all", false); 98 int vcpu = qdict_get_try_int(qdict, "vcpu", -1); 99 CPUState *cs; 100 101 if (all_cpus) { 102 CPU_FOREACH(cs) { 103 monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index); 104 cpu_dump_state(cs, NULL, CPU_DUMP_FPU); 105 } 106 } else { 107 cs = vcpu >= 0 ? qemu_get_cpu(vcpu) : mon_get_cpu(mon); 108 109 if (!cs) { 110 if (vcpu >= 0) { 111 monitor_printf(mon, "CPU#%d not available\n", vcpu); 112 } else { 113 monitor_printf(mon, "No CPU available\n"); 114 } 115 return; 116 } 117 118 monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index); 119 cpu_dump_state(cs, NULL, CPU_DUMP_FPU); 120 } 121 } 122 123 static void memory_dump(Monitor *mon, int count, int format, int wsize, 124 hwaddr addr, int is_physical) 125 { 126 int l, line_size, i, max_digits, len; 127 uint8_t buf[16]; 128 uint64_t v; 129 CPUState *cs = mon_get_cpu(mon); 130 131 if (!cs && (format == 'i' || !is_physical)) { 132 monitor_printf(mon, "Can not dump without CPU\n"); 133 return; 134 } 135 136 if (format == 'i') { 137 monitor_disas(mon, cs, addr, count, is_physical); 138 return; 139 } 140 141 len = wsize * count; 142 if (wsize == 1) { 143 line_size = 8; 144 } else { 145 line_size = 16; 146 } 147 max_digits = 0; 148 149 switch(format) { 150 case 'o': 151 max_digits = DIV_ROUND_UP(wsize * 8, 3); 152 break; 153 default: 154 case 'x': 155 max_digits = (wsize * 8) / 4; 156 break; 157 case 'u': 158 case 'd': 159 max_digits = DIV_ROUND_UP(wsize * 8 * 10, 33); 160 break; 161 case 'c': 162 wsize = 1; 163 break; 164 } 165 166 while (len > 0) { 167 if (is_physical) { 168 monitor_printf(mon, HWADDR_FMT_plx ":", addr); 169 } else { 170 monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr); 171 } 172 l = len; 173 if (l > line_size) 174 l = line_size; 175 if (is_physical) { 176 AddressSpace *as = cs ? cs->as : &address_space_memory; 177 MemTxResult r = address_space_read(as, addr, 178 MEMTXATTRS_UNSPECIFIED, buf, l); 179 if (r != MEMTX_OK) { 180 monitor_printf(mon, " Cannot access memory\n"); 181 break; 182 } 183 } else { 184 if (cpu_memory_rw_debug(cs, addr, buf, l, 0) < 0) { 185 monitor_printf(mon, " Cannot access memory\n"); 186 break; 187 } 188 } 189 i = 0; 190 while (i < l) { 191 switch(wsize) { 192 default: 193 case 1: 194 v = ldub_p(buf + i); 195 break; 196 case 2: 197 v = lduw_p(buf + i); 198 break; 199 case 4: 200 v = (uint32_t)ldl_p(buf + i); 201 break; 202 case 8: 203 v = ldq_p(buf + i); 204 break; 205 } 206 monitor_printf(mon, " "); 207 switch(format) { 208 case 'o': 209 monitor_printf(mon, "%#*" PRIo64, max_digits, v); 210 break; 211 case 'x': 212 monitor_printf(mon, "0x%0*" PRIx64, max_digits, v); 213 break; 214 case 'u': 215 monitor_printf(mon, "%*" PRIu64, max_digits, v); 216 break; 217 case 'd': 218 monitor_printf(mon, "%*" PRId64, max_digits, v); 219 break; 220 case 'c': 221 monitor_printc(mon, v); 222 break; 223 } 224 i += wsize; 225 } 226 monitor_printf(mon, "\n"); 227 addr += l; 228 len -= l; 229 } 230 } 231 232 void hmp_memory_dump(Monitor *mon, const QDict *qdict) 233 { 234 int count = qdict_get_int(qdict, "count"); 235 int format = qdict_get_int(qdict, "format"); 236 int size = qdict_get_int(qdict, "size"); 237 target_long addr = qdict_get_int(qdict, "addr"); 238 239 memory_dump(mon, count, format, size, addr, 0); 240 } 241 242 void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict) 243 { 244 int count = qdict_get_int(qdict, "count"); 245 int format = qdict_get_int(qdict, "format"); 246 int size = qdict_get_int(qdict, "size"); 247 hwaddr addr = qdict_get_int(qdict, "addr"); 248 249 memory_dump(mon, count, format, size, addr, 1); 250 } 251 252 void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp) 253 { 254 Int128 gpa_region_size; 255 MemoryRegionSection mrs = memory_region_find(get_system_memory(), 256 addr, size); 257 258 if (!mrs.mr) { 259 error_setg(errp, "No memory is mapped at address 0x%" HWADDR_PRIx, addr); 260 return NULL; 261 } 262 263 if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) { 264 error_setg(errp, "Memory at address 0x%" HWADDR_PRIx " is not RAM", addr); 265 memory_region_unref(mrs.mr); 266 return NULL; 267 } 268 269 gpa_region_size = int128_make64(size); 270 if (int128_lt(mrs.size, gpa_region_size)) { 271 error_setg(errp, "Size of memory region at 0x%" HWADDR_PRIx 272 " exceeded.", addr); 273 memory_region_unref(mrs.mr); 274 return NULL; 275 } 276 277 *p_mr = mrs.mr; 278 return qemu_map_ram_ptr(mrs.mr->ram_block, mrs.offset_within_region); 279 } 280 281 void hmp_gpa2hva(Monitor *mon, const QDict *qdict) 282 { 283 hwaddr addr = qdict_get_int(qdict, "addr"); 284 Error *local_err = NULL; 285 MemoryRegion *mr = NULL; 286 void *ptr; 287 288 ptr = gpa2hva(&mr, addr, 1, &local_err); 289 if (local_err) { 290 error_report_err(local_err); 291 return; 292 } 293 294 monitor_printf(mon, "Host virtual address for 0x%" HWADDR_PRIx 295 " (%s) is %p\n", 296 addr, mr->name, ptr); 297 298 memory_region_unref(mr); 299 } 300 301 void hmp_gva2gpa(Monitor *mon, const QDict *qdict) 302 { 303 target_ulong addr = qdict_get_int(qdict, "addr"); 304 MemTxAttrs attrs; 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_attrs_debug(cs, addr & TARGET_PAGE_MASK, &attrs); 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 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 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