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