xref: /openbmc/qemu/monitor/qmp-cmds.c (revision 91f2fa7045e3f6c298b14ea7c66c486c27fe3b9f)
1f1b3ccfaSKevin Wolf /*
2f1b3ccfaSKevin Wolf  * QEMU Management Protocol commands
3f1b3ccfaSKevin Wolf  *
4f1b3ccfaSKevin Wolf  * Copyright IBM, Corp. 2011
5f1b3ccfaSKevin Wolf  *
6f1b3ccfaSKevin Wolf  * Authors:
7f1b3ccfaSKevin Wolf  *  Anthony Liguori   <aliguori@us.ibm.com>
8f1b3ccfaSKevin Wolf  *
9f1b3ccfaSKevin Wolf  * This work is licensed under the terms of the GNU GPL, version 2.  See
10f1b3ccfaSKevin Wolf  * the COPYING file in the top-level directory.
11f1b3ccfaSKevin Wolf  *
12f1b3ccfaSKevin Wolf  * Contributions after 2012-01-13 are licensed under the terms of the
13f1b3ccfaSKevin Wolf  * GNU GPL, version 2 or (at your option) any later version.
14f1b3ccfaSKevin Wolf  */
15f1b3ccfaSKevin Wolf 
16f1b3ccfaSKevin Wolf #include "qemu/osdep.h"
17f1b3ccfaSKevin Wolf #include "qemu-common.h"
18f1b3ccfaSKevin Wolf #include "qemu/cutils.h"
19f1b3ccfaSKevin Wolf #include "qemu/option.h"
20f1b3ccfaSKevin Wolf #include "monitor/monitor.h"
21f1b3ccfaSKevin Wolf #include "sysemu/sysemu.h"
22f1b3ccfaSKevin Wolf #include "qemu/config-file.h"
23f1b3ccfaSKevin Wolf #include "qemu/uuid.h"
24f1b3ccfaSKevin Wolf #include "chardev/char.h"
25f1b3ccfaSKevin Wolf #include "ui/qemu-spice.h"
26fb246f05SPeter Maydell #include "ui/console.h"
27f1b3ccfaSKevin Wolf #include "sysemu/kvm.h"
2854d31236SMarkus Armbruster #include "sysemu/runstate.h"
29e6dba048SAlejandro Jimenez #include "sysemu/runstate-action.h"
30f1b3ccfaSKevin Wolf #include "sysemu/blockdev.h"
31f1b3ccfaSKevin Wolf #include "sysemu/block-backend.h"
32f1b3ccfaSKevin Wolf #include "qapi/error.h"
3327c9188fSPhilippe Mathieu-Daudé #include "qapi/qapi-commands-acpi.h"
345a16818bSKevin Wolf #include "qapi/qapi-commands-block.h"
35fa4dcf57SKevin Wolf #include "qapi/qapi-commands-control.h"
368ac25c84SMarkus Armbruster #include "qapi/qapi-commands-machine.h"
37f1b3ccfaSKevin Wolf #include "qapi/qapi-commands-misc.h"
38f1b3ccfaSKevin Wolf #include "qapi/qapi-commands-ui.h"
3937087fdeSDaniel P. Berrangé #include "qapi/type-helpers.h"
40f1b3ccfaSKevin Wolf #include "qapi/qmp/qerror.h"
41ca411b7cSDaniel P. Berrangé #include "exec/ramlist.h"
42f1b3ccfaSKevin Wolf #include "hw/mem/memory-device.h"
43f1b3ccfaSKevin Wolf #include "hw/acpi/acpi_dev_interface.h"
44*91f2fa70SDaniel P. Berrangé #include "hw/intc/intc.h"
458dbbca5cSDaniel P. Berrangé #include "hw/rdma/rdma.h"
46f1b3ccfaSKevin Wolf 
47f1b3ccfaSKevin Wolf NameInfo *qmp_query_name(Error **errp)
48f1b3ccfaSKevin Wolf {
49f1b3ccfaSKevin Wolf     NameInfo *info = g_malloc0(sizeof(*info));
50f1b3ccfaSKevin Wolf 
51f1b3ccfaSKevin Wolf     if (qemu_name) {
52f1b3ccfaSKevin Wolf         info->has_name = true;
53f1b3ccfaSKevin Wolf         info->name = g_strdup(qemu_name);
54f1b3ccfaSKevin Wolf     }
55f1b3ccfaSKevin Wolf 
56f1b3ccfaSKevin Wolf     return info;
57f1b3ccfaSKevin Wolf }
58f1b3ccfaSKevin Wolf 
59f1b3ccfaSKevin Wolf KvmInfo *qmp_query_kvm(Error **errp)
60f1b3ccfaSKevin Wolf {
61f1b3ccfaSKevin Wolf     KvmInfo *info = g_malloc0(sizeof(*info));
62f1b3ccfaSKevin Wolf 
63f1b3ccfaSKevin Wolf     info->enabled = kvm_enabled();
644f9205beSPeter Maydell     info->present = accel_find("kvm");
65f1b3ccfaSKevin Wolf 
66f1b3ccfaSKevin Wolf     return info;
67f1b3ccfaSKevin Wolf }
68f1b3ccfaSKevin Wolf 
69f1b3ccfaSKevin Wolf UuidInfo *qmp_query_uuid(Error **errp)
70f1b3ccfaSKevin Wolf {
71f1b3ccfaSKevin Wolf     UuidInfo *info = g_malloc0(sizeof(*info));
72f1b3ccfaSKevin Wolf 
73f1b3ccfaSKevin Wolf     info->UUID = qemu_uuid_unparse_strdup(&qemu_uuid);
74f1b3ccfaSKevin Wolf     return info;
75f1b3ccfaSKevin Wolf }
76f1b3ccfaSKevin Wolf 
77f1b3ccfaSKevin Wolf void qmp_quit(Error **errp)
78f1b3ccfaSKevin Wolf {
79e6dba048SAlejandro Jimenez     shutdown_action = SHUTDOWN_ACTION_POWEROFF;
80f1b3ccfaSKevin Wolf     qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT);
81f1b3ccfaSKevin Wolf }
82f1b3ccfaSKevin Wolf 
83f1b3ccfaSKevin Wolf void qmp_stop(Error **errp)
84f1b3ccfaSKevin Wolf {
85f1b3ccfaSKevin Wolf     /* if there is a dump in background, we should wait until the dump
86f1b3ccfaSKevin Wolf      * finished */
87f1b3ccfaSKevin Wolf     if (dump_in_progress()) {
88f1b3ccfaSKevin Wolf         error_setg(errp, "There is a dump in process, please wait.");
89f1b3ccfaSKevin Wolf         return;
90f1b3ccfaSKevin Wolf     }
91f1b3ccfaSKevin Wolf 
92f1b3ccfaSKevin Wolf     if (runstate_check(RUN_STATE_INMIGRATE)) {
93f1b3ccfaSKevin Wolf         autostart = 0;
94f1b3ccfaSKevin Wolf     } else {
95f1b3ccfaSKevin Wolf         vm_stop(RUN_STATE_PAUSED);
96f1b3ccfaSKevin Wolf     }
97f1b3ccfaSKevin Wolf }
98f1b3ccfaSKevin Wolf 
99f1b3ccfaSKevin Wolf void qmp_system_reset(Error **errp)
100f1b3ccfaSKevin Wolf {
101f1b3ccfaSKevin Wolf     qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET);
102f1b3ccfaSKevin Wolf }
103f1b3ccfaSKevin Wolf 
104ec48595eSVladimir Sementsov-Ogievskiy void qmp_system_powerdown(Error **errp)
105f1b3ccfaSKevin Wolf {
106f1b3ccfaSKevin Wolf     qemu_system_powerdown_request();
107f1b3ccfaSKevin Wolf }
108f1b3ccfaSKevin Wolf 
109f1b3ccfaSKevin Wolf void qmp_cont(Error **errp)
110f1b3ccfaSKevin Wolf {
111f1b3ccfaSKevin Wolf     BlockBackend *blk;
11268d00e42SVladimir Sementsov-Ogievskiy     BlockJob *job;
113f1b3ccfaSKevin Wolf     Error *local_err = NULL;
114f1b3ccfaSKevin Wolf 
115f1b3ccfaSKevin Wolf     /* if there is a dump in background, we should wait until the dump
116f1b3ccfaSKevin Wolf      * finished */
117f1b3ccfaSKevin Wolf     if (dump_in_progress()) {
118f1b3ccfaSKevin Wolf         error_setg(errp, "There is a dump in process, please wait.");
119f1b3ccfaSKevin Wolf         return;
120f1b3ccfaSKevin Wolf     }
121f1b3ccfaSKevin Wolf 
122f1b3ccfaSKevin Wolf     if (runstate_needs_reset()) {
123f1b3ccfaSKevin Wolf         error_setg(errp, "Resetting the Virtual Machine is required");
124f1b3ccfaSKevin Wolf         return;
125f1b3ccfaSKevin Wolf     } else if (runstate_check(RUN_STATE_SUSPENDED)) {
126f1b3ccfaSKevin Wolf         return;
127f1b3ccfaSKevin Wolf     } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
128f1b3ccfaSKevin Wolf         error_setg(errp, "Migration is not finalized yet");
129f1b3ccfaSKevin Wolf         return;
130f1b3ccfaSKevin Wolf     }
131f1b3ccfaSKevin Wolf 
132f1b3ccfaSKevin Wolf     for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
133f1b3ccfaSKevin Wolf         blk_iostatus_reset(blk);
134f1b3ccfaSKevin Wolf     }
135f1b3ccfaSKevin Wolf 
13668d00e42SVladimir Sementsov-Ogievskiy     for (job = block_job_next(NULL); job; job = block_job_next(job)) {
13768d00e42SVladimir Sementsov-Ogievskiy         block_job_iostatus_reset(job);
13868d00e42SVladimir Sementsov-Ogievskiy     }
13968d00e42SVladimir Sementsov-Ogievskiy 
140f1b3ccfaSKevin Wolf     /* Continuing after completed migration. Images have been inactivated to
141f1b3ccfaSKevin Wolf      * allow the destination to take control. Need to get control back now.
142f1b3ccfaSKevin Wolf      *
143f1b3ccfaSKevin Wolf      * If there are no inactive block nodes (e.g. because the VM was just
144f1b3ccfaSKevin Wolf      * paused rather than completing a migration), bdrv_inactivate_all() simply
145f1b3ccfaSKevin Wolf      * doesn't do anything. */
146f1b3ccfaSKevin Wolf     bdrv_invalidate_cache_all(&local_err);
147f1b3ccfaSKevin Wolf     if (local_err) {
148f1b3ccfaSKevin Wolf         error_propagate(errp, local_err);
149f1b3ccfaSKevin Wolf         return;
150f1b3ccfaSKevin Wolf     }
151f1b3ccfaSKevin Wolf 
152f1b3ccfaSKevin Wolf     if (runstate_check(RUN_STATE_INMIGRATE)) {
153f1b3ccfaSKevin Wolf         autostart = 1;
154f1b3ccfaSKevin Wolf     } else {
155f1b3ccfaSKevin Wolf         vm_start();
156f1b3ccfaSKevin Wolf     }
157f1b3ccfaSKevin Wolf }
158f1b3ccfaSKevin Wolf 
159f1b3ccfaSKevin Wolf void qmp_system_wakeup(Error **errp)
160f1b3ccfaSKevin Wolf {
161f1b3ccfaSKevin Wolf     if (!qemu_wakeup_suspend_enabled()) {
162f1b3ccfaSKevin Wolf         error_setg(errp,
163f1b3ccfaSKevin Wolf                    "wake-up from suspend is not supported by this guest");
164f1b3ccfaSKevin Wolf         return;
165f1b3ccfaSKevin Wolf     }
166f1b3ccfaSKevin Wolf 
167f1b3ccfaSKevin Wolf     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, errp);
168f1b3ccfaSKevin Wolf }
169f1b3ccfaSKevin Wolf 
170f1b3ccfaSKevin Wolf void qmp_set_password(const char *protocol, const char *password,
171f1b3ccfaSKevin Wolf                       bool has_connected, const char *connected, Error **errp)
172f1b3ccfaSKevin Wolf {
173f1b3ccfaSKevin Wolf     int disconnect_if_connected = 0;
174f1b3ccfaSKevin Wolf     int fail_if_connected = 0;
175f1b3ccfaSKevin Wolf     int rc;
176f1b3ccfaSKevin Wolf 
177f1b3ccfaSKevin Wolf     if (has_connected) {
178f1b3ccfaSKevin Wolf         if (strcmp(connected, "fail") == 0) {
179f1b3ccfaSKevin Wolf             fail_if_connected = 1;
180f1b3ccfaSKevin Wolf         } else if (strcmp(connected, "disconnect") == 0) {
181f1b3ccfaSKevin Wolf             disconnect_if_connected = 1;
182f1b3ccfaSKevin Wolf         } else if (strcmp(connected, "keep") == 0) {
183f1b3ccfaSKevin Wolf             /* nothing */
184f1b3ccfaSKevin Wolf         } else {
185f1b3ccfaSKevin Wolf             error_setg(errp, QERR_INVALID_PARAMETER, "connected");
186f1b3ccfaSKevin Wolf             return;
187f1b3ccfaSKevin Wolf         }
188f1b3ccfaSKevin Wolf     }
189f1b3ccfaSKevin Wolf 
190f1b3ccfaSKevin Wolf     if (strcmp(protocol, "spice") == 0) {
191f1b3ccfaSKevin Wolf         if (!qemu_using_spice(errp)) {
192f1b3ccfaSKevin Wolf             return;
193f1b3ccfaSKevin Wolf         }
19408ad2626SGerd Hoffmann         rc = qemu_spice.set_passwd(password, fail_if_connected,
195f1b3ccfaSKevin Wolf                                    disconnect_if_connected);
1969272186dSMarkus Armbruster     } else if (strcmp(protocol, "vnc") == 0) {
197f1b3ccfaSKevin Wolf         if (fail_if_connected || disconnect_if_connected) {
198f1b3ccfaSKevin Wolf             /* vnc supports "connected=keep" only */
199f1b3ccfaSKevin Wolf             error_setg(errp, QERR_INVALID_PARAMETER, "connected");
200f1b3ccfaSKevin Wolf             return;
201f1b3ccfaSKevin Wolf         }
202f1b3ccfaSKevin Wolf         /* Note that setting an empty password will not disable login through
203f1b3ccfaSKevin Wolf          * this interface. */
204f1b3ccfaSKevin Wolf         rc = vnc_display_password(NULL, password);
2059272186dSMarkus Armbruster     } else {
2069272186dSMarkus Armbruster         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "protocol",
2079272186dSMarkus Armbruster                    "'vnc' or 'spice'");
208f1b3ccfaSKevin Wolf         return;
209f1b3ccfaSKevin Wolf     }
210f1b3ccfaSKevin Wolf 
2119272186dSMarkus Armbruster     if (rc != 0) {
2129272186dSMarkus Armbruster         error_setg(errp, "Could not set password");
2139272186dSMarkus Armbruster     }
214f1b3ccfaSKevin Wolf }
215f1b3ccfaSKevin Wolf 
216f1b3ccfaSKevin Wolf void qmp_expire_password(const char *protocol, const char *whenstr,
217f1b3ccfaSKevin Wolf                          Error **errp)
218f1b3ccfaSKevin Wolf {
219f1b3ccfaSKevin Wolf     time_t when;
220f1b3ccfaSKevin Wolf     int rc;
221f1b3ccfaSKevin Wolf 
222f1b3ccfaSKevin Wolf     if (strcmp(whenstr, "now") == 0) {
223f1b3ccfaSKevin Wolf         when = 0;
224f1b3ccfaSKevin Wolf     } else if (strcmp(whenstr, "never") == 0) {
225f1b3ccfaSKevin Wolf         when = TIME_MAX;
226f1b3ccfaSKevin Wolf     } else if (whenstr[0] == '+') {
227f1b3ccfaSKevin Wolf         when = time(NULL) + strtoull(whenstr+1, NULL, 10);
228f1b3ccfaSKevin Wolf     } else {
229f1b3ccfaSKevin Wolf         when = strtoull(whenstr, NULL, 10);
230f1b3ccfaSKevin Wolf     }
231f1b3ccfaSKevin Wolf 
232f1b3ccfaSKevin Wolf     if (strcmp(protocol, "spice") == 0) {
233f1b3ccfaSKevin Wolf         if (!qemu_using_spice(errp)) {
234f1b3ccfaSKevin Wolf             return;
235f1b3ccfaSKevin Wolf         }
23608ad2626SGerd Hoffmann         rc = qemu_spice.set_pw_expire(when);
2379272186dSMarkus Armbruster     } else if (strcmp(protocol, "vnc") == 0) {
238f1b3ccfaSKevin Wolf         rc = vnc_display_pw_expire(NULL, when);
2399272186dSMarkus Armbruster     } else {
2409272186dSMarkus Armbruster         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "protocol",
2419272186dSMarkus Armbruster                    "'vnc' or 'spice'");
242f1b3ccfaSKevin Wolf         return;
243f1b3ccfaSKevin Wolf     }
244f1b3ccfaSKevin Wolf 
2459272186dSMarkus Armbruster     if (rc != 0) {
2469272186dSMarkus Armbruster         error_setg(errp, "Could not set password expire time");
2479272186dSMarkus Armbruster     }
248f1b3ccfaSKevin Wolf }
249f1b3ccfaSKevin Wolf 
250f1b3ccfaSKevin Wolf #ifdef CONFIG_VNC
251f1b3ccfaSKevin Wolf void qmp_change_vnc_password(const char *password, Error **errp)
252f1b3ccfaSKevin Wolf {
253f1b3ccfaSKevin Wolf     if (vnc_display_password(NULL, password) < 0) {
2549272186dSMarkus Armbruster         error_setg(errp, "Could not set password");
255f1b3ccfaSKevin Wolf     }
256f1b3ccfaSKevin Wolf }
257f1b3ccfaSKevin Wolf #endif
258f1b3ccfaSKevin Wolf 
259f1b3ccfaSKevin Wolf void qmp_add_client(const char *protocol, const char *fdname,
260f1b3ccfaSKevin Wolf                     bool has_skipauth, bool skipauth, bool has_tls, bool tls,
261f1b3ccfaSKevin Wolf                     Error **errp)
262f1b3ccfaSKevin Wolf {
263f1b3ccfaSKevin Wolf     Chardev *s;
264f1b3ccfaSKevin Wolf     int fd;
265f1b3ccfaSKevin Wolf 
266947e4744SKevin Wolf     fd = monitor_get_fd(monitor_cur(), fdname, errp);
267f1b3ccfaSKevin Wolf     if (fd < 0) {
268f1b3ccfaSKevin Wolf         return;
269f1b3ccfaSKevin Wolf     }
270f1b3ccfaSKevin Wolf 
271f1b3ccfaSKevin Wolf     if (strcmp(protocol, "spice") == 0) {
272f1b3ccfaSKevin Wolf         if (!qemu_using_spice(errp)) {
273f1b3ccfaSKevin Wolf             close(fd);
274f1b3ccfaSKevin Wolf             return;
275f1b3ccfaSKevin Wolf         }
276f1b3ccfaSKevin Wolf         skipauth = has_skipauth ? skipauth : false;
277f1b3ccfaSKevin Wolf         tls = has_tls ? tls : false;
278864a024cSGerd Hoffmann         if (qemu_spice.display_add_client(fd, skipauth, tls) < 0) {
279f1b3ccfaSKevin Wolf             error_setg(errp, "spice failed to add client");
280f1b3ccfaSKevin Wolf             close(fd);
281f1b3ccfaSKevin Wolf         }
282f1b3ccfaSKevin Wolf         return;
283f1b3ccfaSKevin Wolf #ifdef CONFIG_VNC
284f1b3ccfaSKevin Wolf     } else if (strcmp(protocol, "vnc") == 0) {
285f1b3ccfaSKevin Wolf         skipauth = has_skipauth ? skipauth : false;
286f1b3ccfaSKevin Wolf         vnc_display_add_client(NULL, fd, skipauth);
287f1b3ccfaSKevin Wolf         return;
288f1b3ccfaSKevin Wolf #endif
289f1b3ccfaSKevin Wolf     } else if ((s = qemu_chr_find(protocol)) != NULL) {
290f1b3ccfaSKevin Wolf         if (qemu_chr_add_client(s, fd) < 0) {
291f1b3ccfaSKevin Wolf             error_setg(errp, "failed to add client");
292f1b3ccfaSKevin Wolf             close(fd);
293f1b3ccfaSKevin Wolf             return;
294f1b3ccfaSKevin Wolf         }
295f1b3ccfaSKevin Wolf         return;
296f1b3ccfaSKevin Wolf     }
297f1b3ccfaSKevin Wolf 
298f1b3ccfaSKevin Wolf     error_setg(errp, "protocol '%s' is invalid", protocol);
299f1b3ccfaSKevin Wolf     close(fd);
300f1b3ccfaSKevin Wolf }
301f1b3ccfaSKevin Wolf 
302f1b3ccfaSKevin Wolf 
303f1b3ccfaSKevin Wolf MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp)
304f1b3ccfaSKevin Wolf {
305f1b3ccfaSKevin Wolf     return qmp_memory_device_list();
306f1b3ccfaSKevin Wolf }
307f1b3ccfaSKevin Wolf 
308f1b3ccfaSKevin Wolf ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp)
309f1b3ccfaSKevin Wolf {
310f1b3ccfaSKevin Wolf     bool ambig;
311f1b3ccfaSKevin Wolf     ACPIOSTInfoList *head = NULL;
312f1b3ccfaSKevin Wolf     ACPIOSTInfoList **prev = &head;
313f1b3ccfaSKevin Wolf     Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, &ambig);
314f1b3ccfaSKevin Wolf 
315f1b3ccfaSKevin Wolf     if (obj) {
316f1b3ccfaSKevin Wolf         AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj);
317f1b3ccfaSKevin Wolf         AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj);
318f1b3ccfaSKevin Wolf 
319f1b3ccfaSKevin Wolf         adevc->ospm_status(adev, &prev);
320f1b3ccfaSKevin Wolf     } else {
321f1b3ccfaSKevin Wolf         error_setg(errp, "command is not supported, missing ACPI device");
322f1b3ccfaSKevin Wolf     }
323f1b3ccfaSKevin Wolf 
324f1b3ccfaSKevin Wolf     return head;
325f1b3ccfaSKevin Wolf }
326f1b3ccfaSKevin Wolf 
327f1b3ccfaSKevin Wolf MemoryInfo *qmp_query_memory_size_summary(Error **errp)
328f1b3ccfaSKevin Wolf {
329f1b3ccfaSKevin Wolf     MemoryInfo *mem_info = g_malloc0(sizeof(MemoryInfo));
330b326b6eaSPaolo Bonzini     MachineState *ms = MACHINE(qdev_get_machine());
331f1b3ccfaSKevin Wolf 
332b326b6eaSPaolo Bonzini     mem_info->base_memory = ms->ram_size;
333f1b3ccfaSKevin Wolf 
334f1b3ccfaSKevin Wolf     mem_info->plugged_memory = get_plugged_memory_size();
335f1b3ccfaSKevin Wolf     mem_info->has_plugged_memory =
336f1b3ccfaSKevin Wolf         mem_info->plugged_memory != (uint64_t)-1;
337f1b3ccfaSKevin Wolf 
338f1b3ccfaSKevin Wolf     return mem_info;
339f1b3ccfaSKevin Wolf }
3409cc07651SZihao Chang 
3419cc07651SZihao Chang void qmp_display_reload(DisplayReloadOptions *arg, Error **errp)
3429cc07651SZihao Chang {
3439cc07651SZihao Chang     switch (arg->type) {
3449cc07651SZihao Chang     case DISPLAY_RELOAD_TYPE_VNC:
3459cc07651SZihao Chang #ifdef CONFIG_VNC
3469cc07651SZihao Chang         if (arg->u.vnc.has_tls_certs && arg->u.vnc.tls_certs) {
3479cc07651SZihao Chang             vnc_display_reload_certs(NULL, errp);
3489cc07651SZihao Chang         }
3499cc07651SZihao Chang #else
3509cc07651SZihao Chang         error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'");
3519cc07651SZihao Chang #endif
3529cc07651SZihao Chang         break;
3539cc07651SZihao Chang     default:
3549cc07651SZihao Chang         abort();
3559cc07651SZihao Chang     }
3569cc07651SZihao Chang }
35737087fdeSDaniel P. Berrangé 
35837087fdeSDaniel P. Berrangé #ifdef CONFIG_PROFILER
35937087fdeSDaniel P. Berrangé 
36037087fdeSDaniel P. Berrangé int64_t dev_time;
36137087fdeSDaniel P. Berrangé 
36237087fdeSDaniel P. Berrangé HumanReadableText *qmp_x_query_profile(Error **errp)
36337087fdeSDaniel P. Berrangé {
36437087fdeSDaniel P. Berrangé     g_autoptr(GString) buf = g_string_new("");
36537087fdeSDaniel P. Berrangé     static int64_t last_cpu_exec_time;
36637087fdeSDaniel P. Berrangé     int64_t cpu_exec_time;
36737087fdeSDaniel P. Berrangé     int64_t delta;
36837087fdeSDaniel P. Berrangé 
36937087fdeSDaniel P. Berrangé     cpu_exec_time = tcg_cpu_exec_time();
37037087fdeSDaniel P. Berrangé     delta = cpu_exec_time - last_cpu_exec_time;
37137087fdeSDaniel P. Berrangé 
37237087fdeSDaniel P. Berrangé     g_string_append_printf(buf, "async time  %" PRId64 " (%0.3f)\n",
37337087fdeSDaniel P. Berrangé                            dev_time, dev_time / (double)NANOSECONDS_PER_SECOND);
37437087fdeSDaniel P. Berrangé     g_string_append_printf(buf, "qemu time   %" PRId64 " (%0.3f)\n",
37537087fdeSDaniel P. Berrangé                            delta, delta / (double)NANOSECONDS_PER_SECOND);
37637087fdeSDaniel P. Berrangé     last_cpu_exec_time = cpu_exec_time;
37737087fdeSDaniel P. Berrangé     dev_time = 0;
37837087fdeSDaniel P. Berrangé 
37937087fdeSDaniel P. Berrangé     return human_readable_text_from_str(buf);
38037087fdeSDaniel P. Berrangé }
38137087fdeSDaniel P. Berrangé #else
38237087fdeSDaniel P. Berrangé HumanReadableText *qmp_x_query_profile(Error **errp)
38337087fdeSDaniel P. Berrangé {
38437087fdeSDaniel P. Berrangé     error_setg(errp, "Internal profiler not compiled");
38537087fdeSDaniel P. Berrangé     return NULL;
38637087fdeSDaniel P. Berrangé }
38737087fdeSDaniel P. Berrangé #endif
3888dbbca5cSDaniel P. Berrangé 
3898dbbca5cSDaniel P. Berrangé static int qmp_x_query_rdma_foreach(Object *obj, void *opaque)
3908dbbca5cSDaniel P. Berrangé {
3918dbbca5cSDaniel P. Berrangé     RdmaProvider *rdma;
3928dbbca5cSDaniel P. Berrangé     RdmaProviderClass *k;
3938dbbca5cSDaniel P. Berrangé     GString *buf = opaque;
3948dbbca5cSDaniel P. Berrangé 
3958dbbca5cSDaniel P. Berrangé     if (object_dynamic_cast(obj, INTERFACE_RDMA_PROVIDER)) {
3968dbbca5cSDaniel P. Berrangé         rdma = RDMA_PROVIDER(obj);
3978dbbca5cSDaniel P. Berrangé         k = RDMA_PROVIDER_GET_CLASS(obj);
3988dbbca5cSDaniel P. Berrangé         if (k->format_statistics) {
3998dbbca5cSDaniel P. Berrangé             k->format_statistics(rdma, buf);
4008dbbca5cSDaniel P. Berrangé         } else {
4018dbbca5cSDaniel P. Berrangé             g_string_append_printf(buf,
4028dbbca5cSDaniel P. Berrangé                                    "RDMA statistics not available for %s.\n",
4038dbbca5cSDaniel P. Berrangé                                    object_get_typename(obj));
4048dbbca5cSDaniel P. Berrangé         }
4058dbbca5cSDaniel P. Berrangé     }
4068dbbca5cSDaniel P. Berrangé 
4078dbbca5cSDaniel P. Berrangé     return 0;
4088dbbca5cSDaniel P. Berrangé }
4098dbbca5cSDaniel P. Berrangé 
4108dbbca5cSDaniel P. Berrangé HumanReadableText *qmp_x_query_rdma(Error **errp)
4118dbbca5cSDaniel P. Berrangé {
4128dbbca5cSDaniel P. Berrangé     g_autoptr(GString) buf = g_string_new("");
4138dbbca5cSDaniel P. Berrangé 
4148dbbca5cSDaniel P. Berrangé     object_child_foreach_recursive(object_get_root(),
4158dbbca5cSDaniel P. Berrangé                                    qmp_x_query_rdma_foreach, buf);
4168dbbca5cSDaniel P. Berrangé 
4178dbbca5cSDaniel P. Berrangé     return human_readable_text_from_str(buf);
4188dbbca5cSDaniel P. Berrangé }
419ca411b7cSDaniel P. Berrangé 
420ca411b7cSDaniel P. Berrangé HumanReadableText *qmp_x_query_ramblock(Error **errp)
421ca411b7cSDaniel P. Berrangé {
422ca411b7cSDaniel P. Berrangé     g_autoptr(GString) buf = ram_block_format();
423ca411b7cSDaniel P. Berrangé 
424ca411b7cSDaniel P. Berrangé     return human_readable_text_from_str(buf);
425ca411b7cSDaniel P. Berrangé }
426*91f2fa70SDaniel P. Berrangé 
427*91f2fa70SDaniel P. Berrangé static int qmp_x_query_irq_foreach(Object *obj, void *opaque)
428*91f2fa70SDaniel P. Berrangé {
429*91f2fa70SDaniel P. Berrangé     InterruptStatsProvider *intc;
430*91f2fa70SDaniel P. Berrangé     InterruptStatsProviderClass *k;
431*91f2fa70SDaniel P. Berrangé     GString *buf = opaque;
432*91f2fa70SDaniel P. Berrangé 
433*91f2fa70SDaniel P. Berrangé     if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) {
434*91f2fa70SDaniel P. Berrangé         intc = INTERRUPT_STATS_PROVIDER(obj);
435*91f2fa70SDaniel P. Berrangé         k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj);
436*91f2fa70SDaniel P. Berrangé         uint64_t *irq_counts;
437*91f2fa70SDaniel P. Berrangé         unsigned int nb_irqs, i;
438*91f2fa70SDaniel P. Berrangé         if (k->get_statistics &&
439*91f2fa70SDaniel P. Berrangé             k->get_statistics(intc, &irq_counts, &nb_irqs)) {
440*91f2fa70SDaniel P. Berrangé             if (nb_irqs > 0) {
441*91f2fa70SDaniel P. Berrangé                 g_string_append_printf(buf, "IRQ statistics for %s:\n",
442*91f2fa70SDaniel P. Berrangé                                        object_get_typename(obj));
443*91f2fa70SDaniel P. Berrangé                 for (i = 0; i < nb_irqs; i++) {
444*91f2fa70SDaniel P. Berrangé                     if (irq_counts[i] > 0) {
445*91f2fa70SDaniel P. Berrangé                         g_string_append_printf(buf, "%2d: %" PRId64 "\n", i,
446*91f2fa70SDaniel P. Berrangé                                                irq_counts[i]);
447*91f2fa70SDaniel P. Berrangé                     }
448*91f2fa70SDaniel P. Berrangé                 }
449*91f2fa70SDaniel P. Berrangé             }
450*91f2fa70SDaniel P. Berrangé         } else {
451*91f2fa70SDaniel P. Berrangé             g_string_append_printf(buf,
452*91f2fa70SDaniel P. Berrangé                                    "IRQ statistics not available for %s.\n",
453*91f2fa70SDaniel P. Berrangé                                    object_get_typename(obj));
454*91f2fa70SDaniel P. Berrangé         }
455*91f2fa70SDaniel P. Berrangé     }
456*91f2fa70SDaniel P. Berrangé 
457*91f2fa70SDaniel P. Berrangé     return 0;
458*91f2fa70SDaniel P. Berrangé }
459*91f2fa70SDaniel P. Berrangé 
460*91f2fa70SDaniel P. Berrangé HumanReadableText *qmp_x_query_irq(Error **errp)
461*91f2fa70SDaniel P. Berrangé {
462*91f2fa70SDaniel P. Berrangé     g_autoptr(GString) buf = g_string_new("");
463*91f2fa70SDaniel P. Berrangé 
464*91f2fa70SDaniel P. Berrangé     object_child_foreach_recursive(object_get_root(),
465*91f2fa70SDaniel P. Berrangé                                    qmp_x_query_irq_foreach, buf);
466*91f2fa70SDaniel P. Berrangé 
467*91f2fa70SDaniel P. Berrangé     return human_readable_text_from_str(buf);
468*91f2fa70SDaniel P. Berrangé }
469