xref: /qemu/hw/virtio/virtio-hmp-cmds.c (revision c3bef3b4)
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