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. */ 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. */ 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 77 CPUState *mon_get_cpu(Monitor *mon) 78 { 79 return mon_get_cpu_sync(mon, true); 80 } 81 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 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 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 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 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 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 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 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 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 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