1 /* 2 * HMP commands related to virtio 3 * 4 * This work is licensed under the terms of the GNU GPL, version 2 or 5 * (at your option) any later version. 6 */ 7 8 #include "qemu/osdep.h" 9 #include "monitor/hmp.h" 10 #include "monitor/monitor.h" 11 #include "qapi/qapi-commands-virtio.h" 12 #include "qapi/qmp/qdict.h" 13 14 15 static void hmp_virtio_dump_protocols(Monitor *mon, 16 VhostDeviceProtocols *pcol) 17 { 18 strList *pcol_list = pcol->protocols; 19 while (pcol_list) { 20 monitor_printf(mon, "\t%s", pcol_list->value); 21 pcol_list = pcol_list->next; 22 if (pcol_list != NULL) { 23 monitor_printf(mon, ",\n"); 24 } 25 } 26 monitor_printf(mon, "\n"); 27 if (pcol->has_unknown_protocols) { 28 monitor_printf(mon, " unknown-protocols(0x%016"PRIx64")\n", 29 pcol->unknown_protocols); 30 } 31 } 32 33 static void hmp_virtio_dump_status(Monitor *mon, 34 VirtioDeviceStatus *status) 35 { 36 strList *status_list = status->statuses; 37 while (status_list) { 38 monitor_printf(mon, "\t%s", status_list->value); 39 status_list = status_list->next; 40 if (status_list != NULL) { 41 monitor_printf(mon, ",\n"); 42 } 43 } 44 monitor_printf(mon, "\n"); 45 if (status->has_unknown_statuses) { 46 monitor_printf(mon, " unknown-statuses(0x%016"PRIx32")\n", 47 status->unknown_statuses); 48 } 49 } 50 51 static void hmp_virtio_dump_features(Monitor *mon, 52 VirtioDeviceFeatures *features) 53 { 54 strList *transport_list = features->transports; 55 while (transport_list) { 56 monitor_printf(mon, "\t%s", transport_list->value); 57 transport_list = transport_list->next; 58 if (transport_list != NULL) { 59 monitor_printf(mon, ",\n"); 60 } 61 } 62 63 monitor_printf(mon, "\n"); 64 strList *list = features->dev_features; 65 if (list) { 66 while (list) { 67 monitor_printf(mon, "\t%s", list->value); 68 list = list->next; 69 if (list != NULL) { 70 monitor_printf(mon, ",\n"); 71 } 72 } 73 monitor_printf(mon, "\n"); 74 } 75 76 if (features->has_unknown_dev_features) { 77 monitor_printf(mon, " unknown-features(0x%016"PRIx64")\n", 78 features->unknown_dev_features); 79 } 80 } 81 82 void hmp_virtio_query(Monitor *mon, const QDict *qdict) 83 { 84 Error *err = NULL; 85 VirtioInfoList *list = qmp_x_query_virtio(&err); 86 VirtioInfoList *node; 87 88 if (err != NULL) { 89 hmp_handle_error(mon, err); 90 return; 91 } 92 93 if (list == NULL) { 94 monitor_printf(mon, "No VirtIO devices\n"); 95 return; 96 } 97 98 node = list; 99 while (node) { 100 monitor_printf(mon, "%s [%s]\n", node->value->path, 101 node->value->name); 102 node = node->next; 103 } 104 qapi_free_VirtioInfoList(list); 105 } 106 107 void hmp_virtio_status(Monitor *mon, const QDict *qdict) 108 { 109 Error *err = NULL; 110 const char *path = qdict_get_try_str(qdict, "path"); 111 VirtioStatus *s = qmp_x_query_virtio_status(path, &err); 112 113 if (err != NULL) { 114 hmp_handle_error(mon, err); 115 return; 116 } 117 118 monitor_printf(mon, "%s:\n", path); 119 monitor_printf(mon, " device_name: %s %s\n", 120 s->name, s->vhost_dev ? "(vhost)" : ""); 121 monitor_printf(mon, " device_id: %d\n", s->device_id); 122 monitor_printf(mon, " vhost_started: %s\n", 123 s->vhost_started ? "true" : "false"); 124 monitor_printf(mon, " bus_name: %s\n", s->bus_name); 125 monitor_printf(mon, " broken: %s\n", 126 s->broken ? "true" : "false"); 127 monitor_printf(mon, " disabled: %s\n", 128 s->disabled ? "true" : "false"); 129 monitor_printf(mon, " disable_legacy_check: %s\n", 130 s->disable_legacy_check ? "true" : "false"); 131 monitor_printf(mon, " started: %s\n", 132 s->started ? "true" : "false"); 133 monitor_printf(mon, " use_started: %s\n", 134 s->use_started ? "true" : "false"); 135 monitor_printf(mon, " start_on_kick: %s\n", 136 s->start_on_kick ? "true" : "false"); 137 monitor_printf(mon, " use_guest_notifier_mask: %s\n", 138 s->use_guest_notifier_mask ? "true" : "false"); 139 monitor_printf(mon, " vm_running: %s\n", 140 s->vm_running ? "true" : "false"); 141 monitor_printf(mon, " num_vqs: %"PRId64"\n", s->num_vqs); 142 monitor_printf(mon, " queue_sel: %d\n", 143 s->queue_sel); 144 monitor_printf(mon, " isr: %d\n", s->isr); 145 monitor_printf(mon, " endianness: %s\n", 146 s->device_endian); 147 monitor_printf(mon, " status:\n"); 148 hmp_virtio_dump_status(mon, s->status); 149 monitor_printf(mon, " Guest features:\n"); 150 hmp_virtio_dump_features(mon, s->guest_features); 151 monitor_printf(mon, " Host features:\n"); 152 hmp_virtio_dump_features(mon, s->host_features); 153 monitor_printf(mon, " Backend features:\n"); 154 hmp_virtio_dump_features(mon, s->backend_features); 155 156 if (s->vhost_dev) { 157 monitor_printf(mon, " VHost:\n"); 158 monitor_printf(mon, " nvqs: %d\n", 159 s->vhost_dev->nvqs); 160 monitor_printf(mon, " vq_index: %"PRId64"\n", 161 s->vhost_dev->vq_index); 162 monitor_printf(mon, " max_queues: %"PRId64"\n", 163 s->vhost_dev->max_queues); 164 monitor_printf(mon, " n_mem_sections: %"PRId64"\n", 165 s->vhost_dev->n_mem_sections); 166 monitor_printf(mon, " n_tmp_sections: %"PRId64"\n", 167 s->vhost_dev->n_tmp_sections); 168 monitor_printf(mon, " backend_cap: %"PRId64"\n", 169 s->vhost_dev->backend_cap); 170 monitor_printf(mon, " log_enabled: %s\n", 171 s->vhost_dev->log_enabled ? "true" : "false"); 172 monitor_printf(mon, " log_size: %"PRId64"\n", 173 s->vhost_dev->log_size); 174 monitor_printf(mon, " Features:\n"); 175 hmp_virtio_dump_features(mon, s->vhost_dev->features); 176 monitor_printf(mon, " Acked features:\n"); 177 hmp_virtio_dump_features(mon, s->vhost_dev->acked_features); 178 monitor_printf(mon, " Backend features:\n"); 179 hmp_virtio_dump_features(mon, s->vhost_dev->backend_features); 180 monitor_printf(mon, " Protocol features:\n"); 181 hmp_virtio_dump_protocols(mon, s->vhost_dev->protocol_features); 182 } 183 184 qapi_free_VirtioStatus(s); 185 } 186 187 void hmp_vhost_queue_status(Monitor *mon, const QDict *qdict) 188 { 189 Error *err = NULL; 190 const char *path = qdict_get_try_str(qdict, "path"); 191 int queue = qdict_get_int(qdict, "queue"); 192 VirtVhostQueueStatus *s = 193 qmp_x_query_virtio_vhost_queue_status(path, queue, &err); 194 195 if (err != NULL) { 196 hmp_handle_error(mon, err); 197 return; 198 } 199 200 monitor_printf(mon, "%s:\n", path); 201 monitor_printf(mon, " device_name: %s (vhost)\n", 202 s->name); 203 monitor_printf(mon, " kick: %"PRId64"\n", s->kick); 204 monitor_printf(mon, " call: %"PRId64"\n", s->call); 205 monitor_printf(mon, " VRing:\n"); 206 monitor_printf(mon, " num: %"PRId64"\n", s->num); 207 monitor_printf(mon, " desc: 0x%016"PRIx64"\n", s->desc); 208 monitor_printf(mon, " desc_phys: 0x%016"PRIx64"\n", 209 s->desc_phys); 210 monitor_printf(mon, " desc_size: %"PRId32"\n", s->desc_size); 211 monitor_printf(mon, " avail: 0x%016"PRIx64"\n", s->avail); 212 monitor_printf(mon, " avail_phys: 0x%016"PRIx64"\n", 213 s->avail_phys); 214 monitor_printf(mon, " avail_size: %"PRId32"\n", s->avail_size); 215 monitor_printf(mon, " used: 0x%016"PRIx64"\n", s->used); 216 monitor_printf(mon, " used_phys: 0x%016"PRIx64"\n", 217 s->used_phys); 218 monitor_printf(mon, " used_size: %"PRId32"\n", s->used_size); 219 220 qapi_free_VirtVhostQueueStatus(s); 221 } 222 223 void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict) 224 { 225 Error *err = NULL; 226 const char *path = qdict_get_try_str(qdict, "path"); 227 int queue = qdict_get_int(qdict, "queue"); 228 VirtQueueStatus *s = qmp_x_query_virtio_queue_status(path, queue, &err); 229 230 if (err != NULL) { 231 hmp_handle_error(mon, err); 232 return; 233 } 234 235 monitor_printf(mon, "%s:\n", path); 236 monitor_printf(mon, " device_name: %s\n", s->name); 237 monitor_printf(mon, " queue_index: %d\n", s->queue_index); 238 monitor_printf(mon, " inuse: %d\n", s->inuse); 239 monitor_printf(mon, " used_idx: %d\n", s->used_idx); 240 monitor_printf(mon, " signalled_used: %d\n", 241 s->signalled_used); 242 monitor_printf(mon, " signalled_used_valid: %s\n", 243 s->signalled_used_valid ? "true" : "false"); 244 if (s->has_last_avail_idx) { 245 monitor_printf(mon, " last_avail_idx: %d\n", 246 s->last_avail_idx); 247 } 248 if (s->has_shadow_avail_idx) { 249 monitor_printf(mon, " shadow_avail_idx: %d\n", 250 s->shadow_avail_idx); 251 } 252 monitor_printf(mon, " VRing:\n"); 253 monitor_printf(mon, " num: %"PRId32"\n", s->vring_num); 254 monitor_printf(mon, " num_default: %"PRId32"\n", 255 s->vring_num_default); 256 monitor_printf(mon, " align: %"PRId32"\n", 257 s->vring_align); 258 monitor_printf(mon, " desc: 0x%016"PRIx64"\n", 259 s->vring_desc); 260 monitor_printf(mon, " avail: 0x%016"PRIx64"\n", 261 s->vring_avail); 262 monitor_printf(mon, " used: 0x%016"PRIx64"\n", 263 s->vring_used); 264 265 qapi_free_VirtQueueStatus(s); 266 } 267 268 void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict) 269 { 270 Error *err = NULL; 271 const char *path = qdict_get_try_str(qdict, "path"); 272 int queue = qdict_get_int(qdict, "queue"); 273 int index = qdict_get_try_int(qdict, "index", -1); 274 VirtioQueueElement *e; 275 VirtioRingDescList *list; 276 277 e = qmp_x_query_virtio_queue_element(path, queue, index != -1, 278 index, &err); 279 if (err != NULL) { 280 hmp_handle_error(mon, err); 281 return; 282 } 283 284 monitor_printf(mon, "%s:\n", path); 285 monitor_printf(mon, " device_name: %s\n", e->name); 286 monitor_printf(mon, " index: %d\n", e->index); 287 monitor_printf(mon, " desc:\n"); 288 monitor_printf(mon, " descs:\n"); 289 290 list = e->descs; 291 while (list) { 292 monitor_printf(mon, " addr 0x%"PRIx64" len %d", 293 list->value->addr, list->value->len); 294 if (list->value->flags) { 295 strList *flag = list->value->flags; 296 monitor_printf(mon, " ("); 297 while (flag) { 298 monitor_printf(mon, "%s", flag->value); 299 flag = flag->next; 300 if (flag) { 301 monitor_printf(mon, ", "); 302 } 303 } 304 monitor_printf(mon, ")"); 305 } 306 list = list->next; 307 if (list) { 308 monitor_printf(mon, ",\n"); 309 } 310 } 311 monitor_printf(mon, "\n"); 312 monitor_printf(mon, " avail:\n"); 313 monitor_printf(mon, " flags: %d\n", e->avail->flags); 314 monitor_printf(mon, " idx: %d\n", e->avail->idx); 315 monitor_printf(mon, " ring: %d\n", e->avail->ring); 316 monitor_printf(mon, " used:\n"); 317 monitor_printf(mon, " flags: %d\n", e->used->flags); 318 monitor_printf(mon, " idx: %d\n", e->used->idx); 319 320 qapi_free_VirtioQueueElement(e); 321 } 322