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