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