1 /* 2 * HMP commands related to machines and CPUs 3 * 4 * Copyright IBM, Corp. 2011 5 * 6 * Authors: 7 * Anthony Liguori <aliguori@us.ibm.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2. See 10 * the COPYING file in the top-level directory. 11 * 12 * Contributions after 2012-01-13 are licensed under the terms of the 13 * GNU GPL, version 2 or (at your option) any later version. 14 */ 15 16 #include "qemu/osdep.h" 17 #include "monitor/hmp.h" 18 #include "monitor/monitor.h" 19 #include "qapi/error.h" 20 #include "qapi/qapi-builtin-visit.h" 21 #include "qapi/qapi-commands-accelerator.h" 22 #include "qapi/qapi-commands-machine.h" 23 #include "qobject/qdict.h" 24 #include "qapi/string-output-visitor.h" 25 #include "qemu/error-report.h" 26 #include "system/numa.h" 27 #include "hw/boards.h" 28 29 void hmp_info_cpus(Monitor *mon, const QDict *qdict) 30 { 31 CpuInfoFastList *cpu_list, *cpu; 32 33 cpu_list = qmp_query_cpus_fast(NULL); 34 35 for (cpu = cpu_list; cpu; cpu = cpu->next) { 36 int active = ' '; 37 38 if (cpu->value->cpu_index == monitor_get_cpu_index(mon)) { 39 active = '*'; 40 } 41 42 monitor_printf(mon, "%c CPU #%" PRId64 ":", active, 43 cpu->value->cpu_index); 44 monitor_printf(mon, " thread_id=%" PRId64 "\n", cpu->value->thread_id); 45 } 46 47 qapi_free_CpuInfoFastList(cpu_list); 48 } 49 50 void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict) 51 { 52 Error *err = NULL; 53 HotpluggableCPUList *l = qmp_query_hotpluggable_cpus(&err); 54 HotpluggableCPUList *saved = l; 55 CpuInstanceProperties *c; 56 57 if (hmp_handle_error(mon, err)) { 58 return; 59 } 60 61 monitor_printf(mon, "Hotpluggable CPUs:\n"); 62 while (l) { 63 monitor_printf(mon, " type: \"%s\"\n", l->value->type); 64 monitor_printf(mon, " vcpus_count: \"%" PRIu64 "\"\n", 65 l->value->vcpus_count); 66 if (l->value->qom_path) { 67 monitor_printf(mon, " qom_path: \"%s\"\n", l->value->qom_path); 68 } 69 70 c = l->value->props; 71 monitor_printf(mon, " CPUInstance Properties:\n"); 72 if (c->has_node_id) { 73 monitor_printf(mon, " node-id: \"%" PRIu64 "\"\n", c->node_id); 74 } 75 if (c->has_drawer_id) { 76 monitor_printf(mon, " drawer-id: \"%" PRIu64 "\"\n", c->drawer_id); 77 } 78 if (c->has_book_id) { 79 monitor_printf(mon, " book-id: \"%" PRIu64 "\"\n", c->book_id); 80 } 81 if (c->has_socket_id) { 82 monitor_printf(mon, " socket-id: \"%" PRIu64 "\"\n", c->socket_id); 83 } 84 if (c->has_die_id) { 85 monitor_printf(mon, " die-id: \"%" PRIu64 "\"\n", c->die_id); 86 } 87 if (c->has_cluster_id) { 88 monitor_printf(mon, " cluster-id: \"%" PRIu64 "\"\n", 89 c->cluster_id); 90 } 91 if (c->has_module_id) { 92 monitor_printf(mon, " module-id: \"%" PRIu64 "\"\n", 93 c->module_id); 94 } 95 if (c->has_core_id) { 96 monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id); 97 } 98 if (c->has_thread_id) { 99 monitor_printf(mon, " thread-id: \"%" PRIu64 "\"\n", c->thread_id); 100 } 101 102 l = l->next; 103 } 104 105 qapi_free_HotpluggableCPUList(saved); 106 } 107 108 void hmp_info_memdev(Monitor *mon, const QDict *qdict) 109 { 110 Error *err = NULL; 111 MemdevList *memdev_list = qmp_query_memdev(&err); 112 MemdevList *m = memdev_list; 113 Visitor *v; 114 char *str; 115 116 while (m) { 117 v = string_output_visitor_new(false, &str); 118 visit_type_uint16List(v, NULL, &m->value->host_nodes, &error_abort); 119 monitor_printf(mon, "memory backend: %s\n", m->value->id); 120 monitor_printf(mon, " size: %" PRId64 "\n", m->value->size); 121 monitor_printf(mon, " merge: %s\n", 122 m->value->merge ? "true" : "false"); 123 monitor_printf(mon, " dump: %s\n", 124 m->value->dump ? "true" : "false"); 125 monitor_printf(mon, " prealloc: %s\n", 126 m->value->prealloc ? "true" : "false"); 127 monitor_printf(mon, " share: %s\n", 128 m->value->share ? "true" : "false"); 129 if (m->value->has_reserve) { 130 monitor_printf(mon, " reserve: %s\n", 131 m->value->reserve ? "true" : "false"); 132 } 133 monitor_printf(mon, " policy: %s\n", 134 HostMemPolicy_str(m->value->policy)); 135 visit_complete(v, &str); 136 monitor_printf(mon, " host nodes: %s\n", str); 137 138 g_free(str); 139 visit_free(v); 140 m = m->next; 141 } 142 143 monitor_printf(mon, "\n"); 144 145 qapi_free_MemdevList(memdev_list); 146 hmp_handle_error(mon, err); 147 } 148 149 void hmp_info_kvm(Monitor *mon, const QDict *qdict) 150 { 151 KvmInfo *info; 152 153 info = qmp_query_kvm(NULL); 154 monitor_printf(mon, "kvm support: "); 155 if (info->present) { 156 monitor_printf(mon, "%s\n", info->enabled ? "enabled" : "disabled"); 157 } else { 158 monitor_printf(mon, "not compiled\n"); 159 } 160 161 qapi_free_KvmInfo(info); 162 } 163 164 void hmp_info_uuid(Monitor *mon, const QDict *qdict) 165 { 166 UuidInfo *info; 167 168 info = qmp_query_uuid(NULL); 169 monitor_printf(mon, "%s\n", info->UUID); 170 qapi_free_UuidInfo(info); 171 } 172 173 void hmp_info_balloon(Monitor *mon, const QDict *qdict) 174 { 175 BalloonInfo *info; 176 Error *err = NULL; 177 178 info = qmp_query_balloon(&err); 179 if (hmp_handle_error(mon, err)) { 180 return; 181 } 182 183 monitor_printf(mon, "balloon: actual=%" PRId64 "\n", info->actual >> 20); 184 185 qapi_free_BalloonInfo(info); 186 } 187 188 void hmp_system_reset(Monitor *mon, const QDict *qdict) 189 { 190 qmp_system_reset(NULL); 191 } 192 193 void hmp_system_powerdown(Monitor *mon, const QDict *qdict) 194 { 195 qmp_system_powerdown(NULL); 196 } 197 198 void hmp_memsave(Monitor *mon, const QDict *qdict) 199 { 200 uint32_t size = qdict_get_int(qdict, "size"); 201 const char *filename = qdict_get_str(qdict, "filename"); 202 uint64_t addr = qdict_get_int(qdict, "val"); 203 Error *err = NULL; 204 int cpu_index = monitor_get_cpu_index(mon); 205 206 if (cpu_index < 0) { 207 monitor_printf(mon, "No CPU available\n"); 208 return; 209 } 210 211 qmp_memsave(addr, size, filename, true, cpu_index, &err); 212 hmp_handle_error(mon, err); 213 } 214 215 void hmp_pmemsave(Monitor *mon, const QDict *qdict) 216 { 217 uint32_t size = qdict_get_int(qdict, "size"); 218 const char *filename = qdict_get_str(qdict, "filename"); 219 uint64_t addr = qdict_get_int(qdict, "val"); 220 Error *err = NULL; 221 222 qmp_pmemsave(addr, size, filename, &err); 223 hmp_handle_error(mon, err); 224 } 225 226 void hmp_system_wakeup(Monitor *mon, const QDict *qdict) 227 { 228 Error *err = NULL; 229 230 qmp_system_wakeup(&err); 231 hmp_handle_error(mon, err); 232 } 233 234 void hmp_nmi(Monitor *mon, const QDict *qdict) 235 { 236 Error *err = NULL; 237 238 qmp_inject_nmi(&err); 239 hmp_handle_error(mon, err); 240 } 241 242 void hmp_balloon(Monitor *mon, const QDict *qdict) 243 { 244 int64_t value = qdict_get_int(qdict, "value"); 245 Error *err = NULL; 246 247 qmp_balloon(value, &err); 248 hmp_handle_error(mon, err); 249 } 250 251 void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) 252 { 253 Error *err = NULL; 254 MemoryDeviceInfoList *info_list = qmp_query_memory_devices(&err); 255 MemoryDeviceInfoList *info; 256 VirtioPMEMDeviceInfo *vpi; 257 VirtioMEMDeviceInfo *vmi; 258 MemoryDeviceInfo *value; 259 PCDIMMDeviceInfo *di; 260 SgxEPCDeviceInfo *se; 261 HvBalloonDeviceInfo *hi; 262 263 for (info = info_list; info; info = info->next) { 264 value = info->value; 265 266 if (value) { 267 switch (value->type) { 268 case MEMORY_DEVICE_INFO_KIND_DIMM: 269 case MEMORY_DEVICE_INFO_KIND_NVDIMM: 270 di = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ? 271 value->u.dimm.data : value->u.nvdimm.data; 272 monitor_printf(mon, "Memory device [%s]: \"%s\"\n", 273 MemoryDeviceInfoKind_str(value->type), 274 di->id ? di->id : ""); 275 monitor_printf(mon, " addr: 0x%" PRIx64 "\n", di->addr); 276 monitor_printf(mon, " slot: %" PRId64 "\n", di->slot); 277 monitor_printf(mon, " node: %" PRId64 "\n", di->node); 278 monitor_printf(mon, " size: %" PRIu64 "\n", di->size); 279 monitor_printf(mon, " memdev: %s\n", di->memdev); 280 monitor_printf(mon, " hotplugged: %s\n", 281 di->hotplugged ? "true" : "false"); 282 monitor_printf(mon, " hotpluggable: %s\n", 283 di->hotpluggable ? "true" : "false"); 284 break; 285 case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM: 286 vpi = value->u.virtio_pmem.data; 287 monitor_printf(mon, "Memory device [%s]: \"%s\"\n", 288 MemoryDeviceInfoKind_str(value->type), 289 vpi->id ? vpi->id : ""); 290 monitor_printf(mon, " memaddr: 0x%" PRIx64 "\n", vpi->memaddr); 291 monitor_printf(mon, " size: %" PRIu64 "\n", vpi->size); 292 monitor_printf(mon, " memdev: %s\n", vpi->memdev); 293 break; 294 case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM: 295 vmi = value->u.virtio_mem.data; 296 monitor_printf(mon, "Memory device [%s]: \"%s\"\n", 297 MemoryDeviceInfoKind_str(value->type), 298 vmi->id ? vmi->id : ""); 299 monitor_printf(mon, " memaddr: 0x%" PRIx64 "\n", vmi->memaddr); 300 monitor_printf(mon, " node: %" PRId64 "\n", vmi->node); 301 monitor_printf(mon, " requested-size: %" PRIu64 "\n", 302 vmi->requested_size); 303 monitor_printf(mon, " size: %" PRIu64 "\n", vmi->size); 304 monitor_printf(mon, " max-size: %" PRIu64 "\n", vmi->max_size); 305 monitor_printf(mon, " block-size: %" PRIu64 "\n", 306 vmi->block_size); 307 monitor_printf(mon, " memdev: %s\n", vmi->memdev); 308 break; 309 case MEMORY_DEVICE_INFO_KIND_SGX_EPC: 310 se = value->u.sgx_epc.data; 311 monitor_printf(mon, "Memory device [%s]: \"%s\"\n", 312 MemoryDeviceInfoKind_str(value->type), 313 se->id ? se->id : ""); 314 monitor_printf(mon, " memaddr: 0x%" PRIx64 "\n", se->memaddr); 315 monitor_printf(mon, " size: %" PRIu64 "\n", se->size); 316 monitor_printf(mon, " node: %" PRId64 "\n", se->node); 317 monitor_printf(mon, " memdev: %s\n", se->memdev); 318 break; 319 case MEMORY_DEVICE_INFO_KIND_HV_BALLOON: 320 hi = value->u.hv_balloon.data; 321 monitor_printf(mon, "Memory device [%s]: \"%s\"\n", 322 MemoryDeviceInfoKind_str(value->type), 323 hi->id ? hi->id : ""); 324 if (hi->has_memaddr) { 325 monitor_printf(mon, " memaddr: 0x%" PRIx64 "\n", 326 hi->memaddr); 327 } 328 monitor_printf(mon, " max-size: %" PRIu64 "\n", hi->max_size); 329 if (hi->memdev) { 330 monitor_printf(mon, " memdev: %s\n", hi->memdev); 331 } 332 break; 333 default: 334 g_assert_not_reached(); 335 } 336 } 337 } 338 339 qapi_free_MemoryDeviceInfoList(info_list); 340 hmp_handle_error(mon, err); 341 } 342 343 void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict) 344 { 345 Error *err = NULL; 346 GuidInfo *info = qmp_query_vm_generation_id(&err); 347 if (info) { 348 monitor_printf(mon, "%s\n", info->guid); 349 } 350 hmp_handle_error(mon, err); 351 qapi_free_GuidInfo(info); 352 } 353 354 void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict) 355 { 356 Error *err = NULL; 357 MemoryInfo *info = qmp_query_memory_size_summary(&err); 358 if (info) { 359 monitor_printf(mon, "base memory: %" PRIu64 "\n", 360 info->base_memory); 361 362 if (info->has_plugged_memory) { 363 monitor_printf(mon, "plugged memory: %" PRIu64 "\n", 364 info->plugged_memory); 365 } 366 367 qapi_free_MemoryInfo(info); 368 } 369 hmp_handle_error(mon, err); 370 } 371