| /* |
| * HMP commands related to virtio |
| * |
| * This work is licensed under the terms of the GNU GPL, version 2 or |
| * (at your option) any later version. |
| */ |
| |
| #include "qemu/osdep.h" |
| #include "monitor/hmp.h" |
| #include "monitor/monitor.h" |
| #include "qapi/qapi-commands-virtio.h" |
| #include "qapi/qmp/qdict.h" |
| |
| |
| static void hmp_virtio_dump_protocols(Monitor *mon, |
| VhostDeviceProtocols *pcol) |
| { |
| strList *pcol_list = pcol->protocols; |
| while (pcol_list) { |
| monitor_printf(mon, "\t%s", pcol_list->value); |
| pcol_list = pcol_list->next; |
| if (pcol_list != NULL) { |
| monitor_printf(mon, ",\n"); |
| } |
| } |
| monitor_printf(mon, "\n"); |
| if (pcol->has_unknown_protocols) { |
| monitor_printf(mon, " unknown-protocols(0x%016"PRIx64")\n", |
| pcol->unknown_protocols); |
| } |
| } |
| |
| static void hmp_virtio_dump_status(Monitor *mon, |
| VirtioDeviceStatus *status) |
| { |
| strList *status_list = status->statuses; |
| while (status_list) { |
| monitor_printf(mon, "\t%s", status_list->value); |
| status_list = status_list->next; |
| if (status_list != NULL) { |
| monitor_printf(mon, ",\n"); |
| } |
| } |
| monitor_printf(mon, "\n"); |
| if (status->has_unknown_statuses) { |
| monitor_printf(mon, " unknown-statuses(0x%016"PRIx32")\n", |
| status->unknown_statuses); |
| } |
| } |
| |
| static void hmp_virtio_dump_features(Monitor *mon, |
| VirtioDeviceFeatures *features) |
| { |
| strList *transport_list = features->transports; |
| while (transport_list) { |
| monitor_printf(mon, "\t%s", transport_list->value); |
| transport_list = transport_list->next; |
| if (transport_list != NULL) { |
| monitor_printf(mon, ",\n"); |
| } |
| } |
| |
| monitor_printf(mon, "\n"); |
| strList *list = features->dev_features; |
| if (list) { |
| while (list) { |
| monitor_printf(mon, "\t%s", list->value); |
| list = list->next; |
| if (list != NULL) { |
| monitor_printf(mon, ",\n"); |
| } |
| } |
| monitor_printf(mon, "\n"); |
| } |
| |
| if (features->has_unknown_dev_features) { |
| monitor_printf(mon, " unknown-features(0x%016"PRIx64")\n", |
| features->unknown_dev_features); |
| } |
| } |
| |
| void hmp_virtio_query(Monitor *mon, const QDict *qdict) |
| { |
| Error *err = NULL; |
| VirtioInfoList *list = qmp_x_query_virtio(&err); |
| VirtioInfoList *node; |
| |
| if (err != NULL) { |
| hmp_handle_error(mon, err); |
| return; |
| } |
| |
| if (list == NULL) { |
| monitor_printf(mon, "No VirtIO devices\n"); |
| return; |
| } |
| |
| node = list; |
| while (node) { |
| monitor_printf(mon, "%s [%s]\n", node->value->path, |
| node->value->name); |
| node = node->next; |
| } |
| qapi_free_VirtioInfoList(list); |
| } |
| |
| void hmp_virtio_status(Monitor *mon, const QDict *qdict) |
| { |
| Error *err = NULL; |
| const char *path = qdict_get_try_str(qdict, "path"); |
| VirtioStatus *s = qmp_x_query_virtio_status(path, &err); |
| |
| if (err != NULL) { |
| hmp_handle_error(mon, err); |
| return; |
| } |
| |
| monitor_printf(mon, "%s:\n", path); |
| monitor_printf(mon, " device_name: %s %s\n", |
| s->name, s->vhost_dev ? "(vhost)" : ""); |
| monitor_printf(mon, " device_id: %d\n", s->device_id); |
| monitor_printf(mon, " vhost_started: %s\n", |
| s->vhost_started ? "true" : "false"); |
| monitor_printf(mon, " bus_name: %s\n", s->bus_name); |
| monitor_printf(mon, " broken: %s\n", |
| s->broken ? "true" : "false"); |
| monitor_printf(mon, " disabled: %s\n", |
| s->disabled ? "true" : "false"); |
| monitor_printf(mon, " disable_legacy_check: %s\n", |
| s->disable_legacy_check ? "true" : "false"); |
| monitor_printf(mon, " started: %s\n", |
| s->started ? "true" : "false"); |
| monitor_printf(mon, " use_started: %s\n", |
| s->use_started ? "true" : "false"); |
| monitor_printf(mon, " start_on_kick: %s\n", |
| s->start_on_kick ? "true" : "false"); |
| monitor_printf(mon, " use_guest_notifier_mask: %s\n", |
| s->use_guest_notifier_mask ? "true" : "false"); |
| monitor_printf(mon, " vm_running: %s\n", |
| s->vm_running ? "true" : "false"); |
| monitor_printf(mon, " num_vqs: %"PRId64"\n", s->num_vqs); |
| monitor_printf(mon, " queue_sel: %d\n", |
| s->queue_sel); |
| monitor_printf(mon, " isr: %d\n", s->isr); |
| monitor_printf(mon, " endianness: %s\n", |
| s->device_endian); |
| monitor_printf(mon, " status:\n"); |
| hmp_virtio_dump_status(mon, s->status); |
| monitor_printf(mon, " Guest features:\n"); |
| hmp_virtio_dump_features(mon, s->guest_features); |
| monitor_printf(mon, " Host features:\n"); |
| hmp_virtio_dump_features(mon, s->host_features); |
| monitor_printf(mon, " Backend features:\n"); |
| hmp_virtio_dump_features(mon, s->backend_features); |
| |
| if (s->vhost_dev) { |
| monitor_printf(mon, " VHost:\n"); |
| monitor_printf(mon, " nvqs: %d\n", |
| s->vhost_dev->nvqs); |
| monitor_printf(mon, " vq_index: %"PRId64"\n", |
| s->vhost_dev->vq_index); |
| monitor_printf(mon, " max_queues: %"PRId64"\n", |
| s->vhost_dev->max_queues); |
| monitor_printf(mon, " n_mem_sections: %"PRId64"\n", |
| s->vhost_dev->n_mem_sections); |
| monitor_printf(mon, " n_tmp_sections: %"PRId64"\n", |
| s->vhost_dev->n_tmp_sections); |
| monitor_printf(mon, " backend_cap: %"PRId64"\n", |
| s->vhost_dev->backend_cap); |
| monitor_printf(mon, " log_enabled: %s\n", |
| s->vhost_dev->log_enabled ? "true" : "false"); |
| monitor_printf(mon, " log_size: %"PRId64"\n", |
| s->vhost_dev->log_size); |
| monitor_printf(mon, " Features:\n"); |
| hmp_virtio_dump_features(mon, s->vhost_dev->features); |
| monitor_printf(mon, " Acked features:\n"); |
| hmp_virtio_dump_features(mon, s->vhost_dev->acked_features); |
| monitor_printf(mon, " Backend features:\n"); |
| hmp_virtio_dump_features(mon, s->vhost_dev->backend_features); |
| monitor_printf(mon, " Protocol features:\n"); |
| hmp_virtio_dump_protocols(mon, s->vhost_dev->protocol_features); |
| } |
| |
| qapi_free_VirtioStatus(s); |
| } |
| |
| void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict) |
| { |
| Error *err = NULL; |
| const char *path = qdict_get_try_str(qdict, "path"); |
| int queue = qdict_get_int(qdict, "queue"); |
| VirtVhostQueueStatus *s = |
| qmp_x_query_virtio_vhost_queue_status(path, queue, &err); |
| |
| if (err != NULL) { |
| hmp_handle_error(mon, err); |
| return; |
| } |
| |
| monitor_printf(mon, "%s:\n", path); |
| monitor_printf(mon, " device_name: %s (vhost)\n", |
| s->name); |
| monitor_printf(mon, " kick: %"PRId64"\n", s->kick); |
| monitor_printf(mon, " call: %"PRId64"\n", s->call); |
| monitor_printf(mon, " VRing:\n"); |
| monitor_printf(mon, " num: %"PRId64"\n", s->num); |
| monitor_printf(mon, " desc: 0x%016"PRIx64"\n", s->desc); |
| monitor_printf(mon, " desc_phys: 0x%016"PRIx64"\n", |
| s->desc_phys); |
| monitor_printf(mon, " desc_size: %"PRId32"\n", s->desc_size); |
| monitor_printf(mon, " avail: 0x%016"PRIx64"\n", s->avail); |
| monitor_printf(mon, " avail_phys: 0x%016"PRIx64"\n", |
| s->avail_phys); |
| monitor_printf(mon, " avail_size: %"PRId32"\n", s->avail_size); |
| monitor_printf(mon, " used: 0x%016"PRIx64"\n", s->used); |
| monitor_printf(mon, " used_phys: 0x%016"PRIx64"\n", |
| s->used_phys); |
| monitor_printf(mon, " used_size: %"PRId32"\n", s->used_size); |
| |
| qapi_free_VirtVhostQueueStatus(s); |
| } |
| |
| void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict) |
| { |
| Error *err = NULL; |
| const char *path = qdict_get_try_str(qdict, "path"); |
| int queue = qdict_get_int(qdict, "queue"); |
| VirtQueueStatus *s = qmp_x_query_virtio_queue_status(path, queue, &err); |
| |
| if (err != NULL) { |
| hmp_handle_error(mon, err); |
| return; |
| } |
| |
| monitor_printf(mon, "%s:\n", path); |
| monitor_printf(mon, " device_name: %s\n", s->name); |
| monitor_printf(mon, " queue_index: %d\n", s->queue_index); |
| monitor_printf(mon, " inuse: %d\n", s->inuse); |
| monitor_printf(mon, " used_idx: %d\n", s->used_idx); |
| monitor_printf(mon, " signalled_used: %d\n", |
| s->signalled_used); |
| monitor_printf(mon, " signalled_used_valid: %s\n", |
| s->signalled_used_valid ? "true" : "false"); |
| if (s->has_last_avail_idx) { |
| monitor_printf(mon, " last_avail_idx: %d\n", |
| s->last_avail_idx); |
| } |
| if (s->has_shadow_avail_idx) { |
| monitor_printf(mon, " shadow_avail_idx: %d\n", |
| s->shadow_avail_idx); |
| } |
| monitor_printf(mon, " VRing:\n"); |
| monitor_printf(mon, " num: %"PRId32"\n", s->vring_num); |
| monitor_printf(mon, " num_default: %"PRId32"\n", |
| s->vring_num_default); |
| monitor_printf(mon, " align: %"PRId32"\n", |
| s->vring_align); |
| monitor_printf(mon, " desc: 0x%016"PRIx64"\n", |
| s->vring_desc); |
| monitor_printf(mon, " avail: 0x%016"PRIx64"\n", |
| s->vring_avail); |
| monitor_printf(mon, " used: 0x%016"PRIx64"\n", |
| s->vring_used); |
| |
| qapi_free_VirtQueueStatus(s); |
| } |
| |
| void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict) |
| { |
| Error *err = NULL; |
| const char *path = qdict_get_try_str(qdict, "path"); |
| int queue = qdict_get_int(qdict, "queue"); |
| int index = qdict_get_try_int(qdict, "index", -1); |
| VirtioQueueElement *e; |
| VirtioRingDescList *list; |
| |
| e = qmp_x_query_virtio_queue_element(path, queue, index != -1, |
| index, &err); |
| if (err != NULL) { |
| hmp_handle_error(mon, err); |
| return; |
| } |
| |
| monitor_printf(mon, "%s:\n", path); |
| monitor_printf(mon, " device_name: %s\n", e->name); |
| monitor_printf(mon, " index: %d\n", e->index); |
| monitor_printf(mon, " desc:\n"); |
| monitor_printf(mon, " descs:\n"); |
| |
| list = e->descs; |
| while (list) { |
| monitor_printf(mon, " addr 0x%"PRIx64" len %d", |
| list->value->addr, list->value->len); |
| if (list->value->flags) { |
| strList *flag = list->value->flags; |
| monitor_printf(mon, " ("); |
| while (flag) { |
| monitor_printf(mon, "%s", flag->value); |
| flag = flag->next; |
| if (flag) { |
| monitor_printf(mon, ", "); |
| } |
| } |
| monitor_printf(mon, ")"); |
| } |
| list = list->next; |
| if (list) { |
| monitor_printf(mon, ",\n"); |
| } |
| } |
| monitor_printf(mon, "\n"); |
| monitor_printf(mon, " avail:\n"); |
| monitor_printf(mon, " flags: %d\n", e->avail->flags); |
| monitor_printf(mon, " idx: %d\n", e->avail->idx); |
| monitor_printf(mon, " ring: %d\n", e->avail->ring); |
| monitor_printf(mon, " used:\n"); |
| monitor_printf(mon, " flags: %d\n", e->used->flags); |
| monitor_printf(mon, " idx: %d\n", e->used->idx); |
| |
| qapi_free_VirtioQueueElement(e); |
| } |