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
hmp_info_cpus(Monitor * mon,const QDict * qdict)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
hmp_hotpluggable_cpus(Monitor * mon,const QDict * qdict)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
hmp_info_memdev(Monitor * mon,const QDict * qdict)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
hmp_info_kvm(Monitor * mon,const QDict * qdict)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
hmp_info_uuid(Monitor * mon,const QDict * qdict)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
hmp_info_balloon(Monitor * mon,const QDict * qdict)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
hmp_system_reset(Monitor * mon,const QDict * qdict)190 void hmp_system_reset(Monitor *mon, const QDict *qdict)
191 {
192 qmp_system_reset(NULL);
193 }
194
hmp_system_powerdown(Monitor * mon,const QDict * qdict)195 void hmp_system_powerdown(Monitor *mon, const QDict *qdict)
196 {
197 qmp_system_powerdown(NULL);
198 }
199
hmp_memsave(Monitor * mon,const QDict * qdict)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
hmp_pmemsave(Monitor * mon,const QDict * qdict)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
hmp_system_wakeup(Monitor * mon,const QDict * qdict)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
hmp_nmi(Monitor * mon,const QDict * qdict)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
hmp_balloon(Monitor * mon,const QDict * qdict)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
hmp_info_memory_devices(Monitor * mon,const QDict * qdict)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
hmp_info_vm_generation_id(Monitor * mon,const QDict * qdict)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
hmp_info_memory_size_summary(Monitor * mon,const QDict * qdict)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