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