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