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
hmp_virtio_dump_protocols(Monitor * mon,VhostDeviceProtocols * pcol)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
hmp_virtio_dump_status(Monitor * mon,VirtioDeviceStatus * status)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
hmp_virtio_dump_features(Monitor * mon,VirtioDeviceFeatures * features)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
hmp_virtio_query(Monitor * mon,const QDict * qdict)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
hmp_virtio_status(Monitor * mon,const QDict * qdict)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
hmp_vhost_queue_status(Monitor * mon,const QDict * qdict)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
hmp_virtio_queue_status(Monitor * mon,const QDict * qdict)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
hmp_virtio_queue_element(Monitor * mon,const QDict * qdict)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