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