virtio-hmp-cmds.c 12 KB

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