[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC 5/5] hmp: add virtio commands
From: |
Dr. David Alan Gilbert |
Subject: |
Re: [RFC 5/5] hmp: add virtio commands |
Date: |
Thu, 2 Apr 2020 16:08:07 +0100 |
User-agent: |
Mutt/1.13.4 (2020-02-15) |
* Laurent Vivier (address@hidden) wrote:
> This patch implements HMP version of the virtio QMP commands
>
> Signed-off-by: Laurent Vivier <address@hidden>
> ---
> Makefile | 2 +-
> Makefile.target | 7 +-
> docs/system/monitor.rst | 2 +
> hmp-commands-virtio.hx | 148 ++++++++++++++++++++++++++++++++++++++++
> hmp-commands.hx | 10 +++
> hw/virtio/virtio.c | 115 +++++++++++++++++++++++++++++++
> include/monitor/hmp.h | 4 ++
> monitor/misc.c | 17 +++++
> 8 files changed, 302 insertions(+), 3 deletions(-)
> create mode 100644 hmp-commands-virtio.hx
>
> diff --git a/Makefile b/Makefile
> index 84ef88160006..5f70ea16a566 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1100,7 +1100,7 @@ $(MANUAL_BUILDDIR)/interop/index.html: $(call
> manual-deps,interop)
> $(MANUAL_BUILDDIR)/specs/index.html: $(call manual-deps,specs)
> $(call build-manual,specs,html)
>
> -$(MANUAL_BUILDDIR)/system/index.html: $(call manual-deps,system)
> $(SRC_PATH)/hmp-commands.hx $(SRC_PATH)/hmp-commands-info.hx
> $(SRC_PATH)/qemu-options.hx
> +$(MANUAL_BUILDDIR)/system/index.html: $(call manual-deps,system)
> $(SRC_PATH)/hmp-commands.hx $(SRC_PATH)/hmp-commands-info.hx
> $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/hmp-commands-virtio.hx
> $(call build-manual,system,html)
>
> $(MANUAL_BUILDDIR)/tools/index.html: $(call manual-deps,tools)
> $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/docs/qemu-option-trace.rst.inc
> diff --git a/Makefile.target b/Makefile.target
> index 8ed1eba95b9c..66d3ff9bc350 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -171,7 +171,7 @@ else
> obj-y += hw/$(TARGET_BASE_ARCH)/
> endif
>
> -generated-files-y += hmp-commands.h hmp-commands-info.h
> +generated-files-y += hmp-commands.h hmp-commands-info.h hmp-commands-virtio.h
> generated-files-y += config-devices.h
>
> endif # CONFIG_SOFTMMU
> @@ -220,10 +220,13 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx
> $(SRC_PATH)/scripts/hxtool
> hmp-commands-info.h: $(SRC_PATH)/hmp-commands-info.hx
> $(SRC_PATH)/scripts/hxtool
> $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< >
> $@,"GEN","$(TARGET_DIR)$@")
>
> +hmp-commands-virtio.h: $(SRC_PATH)/hmp-commands-virtio.hx
> $(SRC_PATH)/scripts/hxtool
> + $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< >
> $@,"GEN","$(TARGET_DIR)$@")
> +
(It would be great if these files moved into monitor at some point)
> clean: clean-target
> rm -f *.a *~ $(PROGS)
> rm -f $(shell find . -name '*.[od]')
> - rm -f hmp-commands.h gdbstub-xml.c
> + rm -f hmp-commands.h hmp-commands-virtio.h gdbstub-xml.c
> rm -f trace/generated-helpers.c trace/generated-helpers.c-timestamp
> ifdef CONFIG_TRACE_SYSTEMTAP
> rm -f *.stp
> diff --git a/docs/system/monitor.rst b/docs/system/monitor.rst
> index 0bcd5da21644..985c3f51ffe7 100644
> --- a/docs/system/monitor.rst
> +++ b/docs/system/monitor.rst
> @@ -21,6 +21,8 @@ The following commands are available:
>
> .. hxtool-doc:: hmp-commands.hx
>
> +.. hxtool-doc:: hmp-commands-virtio.hx
> +
> .. hxtool-doc:: hmp-commands-info.hx
>
> Integer expressions
> diff --git a/hmp-commands-virtio.hx b/hmp-commands-virtio.hx
> new file mode 100644
> index 000000000000..a8d49f0b2b46
> --- /dev/null
> +++ b/hmp-commands-virtio.hx
> @@ -0,0 +1,148 @@
> +HXCOMM Use DEFHEADING() to define headings in both help text and rST.
> +HXCOMM Text between SRST and ERST is copied to the rST version and
> +HXCOMM discarded from C version.
> +HXCOMM DEF(command, args, callback, arg_string, help) is used to construct
> +HXCOMM monitor info commands
> +HXCOMM HXCOMM can be used for comments, discarded from both rST and C.
> +HXCOMM
> +HXCOMM In this file, generally SRST fragments should have two extra
> +HXCOMM spaces of indent, so that the documentation list item for "virtio cmd"
> +HXCOMM appears inside the documentation list item for the top level
> +HXCOMM "virtio" documentation entry. The exception is the first SRST
> +HXCOMM fragment that defines that top level entry.
> +
> +SRST
> +``virtio`` *subcommand*
> + Show various information about virtio.
> +
> +ERST
> +
> + {
> + .name = "query",
> + .args_type = "",
> + .params = "",
> + .help = "List all available virtio devices",
> + .cmd = hmp_virtio_query,
> + .flags = "p",
> + },
> +
> +SRST
> + ``virtio query``
> + List all available virtio devices
> +
> + Example:
> +
> + List all available virtio devices in the machine::
> +
> + (qemu) virtio query
> + /machine/peripheral-anon/device[3]/virtio-backend [virtio-net]
> + /machine/peripheral-anon/device[1]/virtio-backend [virtio-serial]
> + /machine/peripheral-anon/device[0]/virtio-backend [virtio-blk]
> +
> +ERST
> +
> + {
> + .name = "status",
> + .args_type = "path:s",
> + .params = "path",
> + .help = "Display status of a given virtio device",
> + .cmd = hmp_virtio_status,
> + .flags = "p",
> + },
> +
> +SRST
> + ``virtio status`` *path*
> + Display status of a given virtio device
> +
> + Example:
> +
> + Dump the status of the first virtio device::
> +
> + (qemu) virtio status /machine/peripheral-anon/device[3]/virtio-backend
> + /machine/peripheral-anon/device[3]/virtio-backend:
> + Device Id: 1
> + Guest features: 0x0000000130afffa7
> + Host features: 0x0000000179bfffe7
> + Backend features: 0x0000000000000000
> + Endianness: little
> + VirtQueues: 3
> +
> +ERST
> +
> + {
> + .name = "queue-status",
> + .args_type = "path:s,queue:i",
> + .params = "path queue",
> + .help = "Display status of a given virtio queue",
> + .cmd = hmp_virtio_queue_status,
> + .flags = "p",
> + },
> +
> +SRST
> + ``virtio queue-status`` *path* *queue*
> + Display status of a given virtio queue
> +
> + Example:
> +
> + Dump the status of the first queue of the first virtio device::
> +
> + (qemu) virtio queue-status
> /machine/peripheral-anon/device[3]/virtio-backend 0
> + /machine/peripheral-anon/device[3]/virtio-backend:
> + index: 0
> + inuse: 0
> + last_avail_idx: 61
> + shadow_avail_idx: 292
> + signalled_used: 61
> + signalled_used_valid: 1
> + VRing:
> + num: 256
> + num_default: 256
> + align: 4096
> + desc: 0x000000006c352000
> + avail: 0x000000006c353000
> + used: 0x000000006c353240
> +
> +ERST
> +
> + {
> + .name = "queue-element",
> + .args_type = "path:s,queue:i,index:i?",
> + .params = "path queue [index]",
> + .help = "Display element of a given virtio queue",
> + .cmd = hmp_virtio_queue_element,
> + .flags = "p",
> + },
> +
> +SRST
> + ``virtio queue-element`` *path* *queue* [*index*]
> + Display element of a given virtio queue
> +
> + Example:
> +
> + Dump the information of the head element of the first queue of
> + the first virtio device::
> +
> + (qemu) virtio
> queue-element/machine/peripheral-anon/device[3]/virtio-backend 0
> + index: 67
> + ndescs: 1
> + descs: addr 0x6fe69800 len 1536 (write-only)
> +
> + (qemu) xp/128bx 0x6fe69800
> + 000000006fe69800: 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
> + 000000006fe69808: 0x00 0x00 0x01 0x00 0x52 0x54 0x00 0x12
> + 000000006fe69810: 0x34 0x56 0x52 0x54 0x00 0x09 0x51 0xde
> + 000000006fe69818: 0x08 0x00 0x45 0x00 0x00 0x4c 0x8f 0x32
> +
> + device[3] is a virtio-net device and we can see in the element buffer the
> + MAC address of the card::
> +
> + [root@localhost ~]# ip link show ens4
> + 2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel
> state UP m0
> + link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
> +
> + and the MAC address of the gateway::
> +
> + [root@localhost ~]# arp -a
> + _gateway (192.168.122.1) at 52:54:00:09:51:de [ether] on ens4
> +
> +ERST
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 7f0f3974ad90..14568b406dbc 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1804,6 +1804,16 @@ SRST
> Set QOM property *property* of object at location *path* to value *value*
> ERST
>
> + {
> + .name = "virtio",
> + .args_type = "name:S?",
> + .params = "[cmd]",
> + .help = "show various information about virtio",
> + .cmd = hmp_virtio_help,
> + .sub_table = hmp_virtio_cmds,
> + .flags = "p",
> + },
> +
> {
> .name = "info",
> .args_type = "item:s?",
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 28848b9e64cf..d52d41169fb4 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -29,6 +29,9 @@
> #include "hw/virtio/virtio-access.h"
> #include "sysemu/dma.h"
> #include "sysemu/runstate.h"
> +#include "monitor/hmp.h"
> +#include "monitor/monitor.h"
> +#include "qapi/qmp/qdict.h"
>
> static QTAILQ_HEAD(, VirtIODevice) virtio_list;
>
> @@ -3839,6 +3842,29 @@ VirtioInfoList *qmp_query_virtio(Error **errp)
> return list;
> }
>
> +void hmp_virtio_query(Monitor *mon, const QDict *qdict)
> +{
> + Error *err = NULL;
> + VirtioInfoList *l = qmp_query_virtio(&err);
> +
> + if (err != NULL) {
> + hmp_handle_error(mon, err);
> + return;
> + }
> +
> + if (l == NULL) {
> + monitor_printf(mon, "No VirtIO devices\n");
> + return;
> + }
> +
> + while (l) {
> + monitor_printf(mon, "%s [%s]\n", l->value->path, l->value->type);
> + l = l->next;
> + }
> +
> + qapi_free_VirtioInfoList(l);
I think you've made the same mistake there that I made in the vnc code;
you're walking 'l' along the list and then freeing l at the end, but l
is always null.
> +}
> +
> static VirtIODevice *virtio_device_find(const char *path)
> {
> VirtIODevice *vdev;
> @@ -3890,6 +3916,36 @@ VirtQueueStatus *qmp_virtio_queue_status(const char
> *path, uint16_t queue,
> return status;
> }
>
> +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_virtio_queue_status(path, queue, &err);
> +
> + if (err != NULL) {
> + hmp_handle_error(mon, err);
> + return;
> + }
> + monitor_printf(mon, "%s:\n", path);
> + monitor_printf(mon, " index: %d\n", s->queue_index);
> + monitor_printf(mon, " inuse: %d\n", s->inuse);
> + monitor_printf(mon, " last_avail_idx: %d\n", s->last_avail_idx);
> + monitor_printf(mon, " shadow_avail_idx: %d\n", s->shadow_avail_idx);
> + monitor_printf(mon, " signalled_used: %d\n", s->signalled_used);
> + monitor_printf(mon, " signalled_used_valid: %d\n",
> + s->signalled_used_valid);
> + monitor_printf(mon, " VRing:\n");
> + monitor_printf(mon, " num: %"PRId64"\n", s->vring_num);
> + monitor_printf(mon, " num_default: %"PRId64"\n",
> s->vring_num_default);
> + monitor_printf(mon, " align: %"PRId64"\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);
> +}
> +
> VirtioStatus *qmp_virtio_status(const char* path, Error **errp)
> {
> VirtIODevice *vdev;
> @@ -3925,6 +3981,31 @@ VirtioStatus *qmp_virtio_status(const char* path,
> Error **errp)
> return status;
> }
>
> +void hmp_virtio_status(Monitor *mon, const QDict *qdict)
> +{
> + Error *err = NULL;
> + const char *path = qdict_get_try_str(qdict, "path");
> + VirtioStatus *s = qmp_virtio_status(path, &err);
> +
> + if (err != NULL) {
> + hmp_handle_error(mon, err);
> + return;
> + }
> +
> + monitor_printf(mon, "%s:\n", path);
> + monitor_printf(mon, " Device Id: %"PRId64"\n", s->device_id);
> + monitor_printf(mon, " Guest features: 0x%016"PRIx64"\n",
> + s->guest_features);
> + monitor_printf(mon, " Host features: 0x%016"PRIx64"\n",
> + s->host_features);
> + monitor_printf(mon, " Backend features: 0x%016"PRIx64"\n",
> + s->backend_features);
> + monitor_printf(mon, " Endianness: %s\n", s->device_endian);
> + monitor_printf(mon, " VirtQueues: %d\n", s->num_vqs);
> +
> + qapi_free_VirtioStatus(s);
> +}
> +
> VirtioQueueElement *qmp_virtio_queue_element(const char* path, uint16_t
> queue,
> bool has_index, uint16_t index,
> Error **errp)
> @@ -4010,6 +4091,40 @@ VirtioQueueElement *qmp_virtio_queue_element(const
> char* path, uint16_t queue,
> return element;
> }
>
> +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 *element;
> + VirtioRingDescList *list;
> +
> + element = qmp_virtio_queue_element(path, queue, index != -1, index,
> &err);
> + if (err != NULL) {
> + hmp_handle_error(mon, err);
> + return;
> + }
> +
> + monitor_printf(mon, "index: %d\n", element->index);
> + monitor_printf(mon, "ndescs: %d\n", element->ndescs);
> + monitor_printf(mon, "descs: ");
> +
> + list = element->descs;
> + while (list) {
> + monitor_printf(mon, "addr 0x%"PRIx64" len %d %s", list->value->addr,
> + list->value->len, list->value->flags &
> + VRING_DESC_F_WRITE ? "(write-only)" : "(read-only)");
> + list = list->next;
> + if (list) {
> + monitor_printf(mon, ", ");
> + }
> + }
> + monitor_printf(mon, "\n");
> +
> + qapi_free_VirtioQueueElement(element);
> +}
> +
> static const TypeInfo virtio_device_info = {
> .name = TYPE_VIRTIO_DEVICE,
> .parent = TYPE_DEVICE,
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index e33ca5a911a5..9f1c118dde31 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -98,6 +98,10 @@ void hmp_info_memory_devices(Monitor *mon, const QDict
> *qdict);
> void hmp_qom_list(Monitor *mon, const QDict *qdict);
> void hmp_qom_set(Monitor *mon, const QDict *qdict);
> void hmp_info_qom_tree(Monitor *mon, const QDict *dict);
> +void hmp_virtio_query(Monitor *mon, const QDict *qdict);
> +void hmp_virtio_status(Monitor *mon, const QDict *qdict);
> +void hmp_virtio_queue_status(Monitor *mon, const QDict *qdict);
> +void hmp_virtio_queue_element(Monitor *mon, const QDict *qdict);
> void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
> void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
> void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
> diff --git a/monitor/misc.c b/monitor/misc.c
> index 6c45fa490ff5..5eacfa7079fc 100644
> --- a/monitor/misc.c
> +++ b/monitor/misc.c
> @@ -23,6 +23,7 @@
> */
>
> #include "qemu/osdep.h"
> +#include "config-devices.h"
> #include "monitor-internal.h"
> #include "cpu.h"
> #include "monitor/qdev.h"
> @@ -232,6 +233,15 @@ static void hmp_info_help(Monitor *mon, const QDict
> *qdict)
> help_cmd(mon, "info");
> }
>
> +static void hmp_virtio_help(Monitor *mon, const QDict *qdict)
> +{
> +#if defined(CONFIG_VIRTIO)
> + help_cmd(mon, "virtio");
> +#else
> + monitor_printf(mon, "Virtio is disabled\n");
> +#endif
> +}
> +
> static void monitor_init_qmp_commands(void)
> {
> /*
> @@ -1683,6 +1693,13 @@ static HMPCommand hmp_info_cmds[] = {
> { NULL, NULL, },
> };
>
> +static HMPCommand hmp_virtio_cmds[] = {
> +#if defined(CONFIG_VIRTIO)
> +#include "hmp-commands-virtio.h"
> +#endif
> + { NULL, NULL, },
> +};
> +
> /* hmp_cmds and hmp_info_cmds would be sorted at runtime */
> HMPCommand hmp_cmds[] = {
> #include "hmp-commands.h"
> --
> 2.25.1
>
--
Dr. David Alan Gilbert / address@hidden / Manchester, UK
- [RFC 1/5] qmp: add QMP command query-virtio, (continued)
- [RFC 1/5] qmp: add QMP command query-virtio, Laurent Vivier, 2020/04/02
- [RFC 2/5] qmp: add QMP command virtio-status, Laurent Vivier, 2020/04/02
- [RFC 3/5] qmp: add QMP command virtio-queue-status, Laurent Vivier, 2020/04/02
- [RFC 4/5] qmp: add QMP command virtio-queue-element, Laurent Vivier, 2020/04/02
- [RFC 5/5] hmp: add virtio commands, Laurent Vivier, 2020/04/02
- Re: [RFC 5/5] hmp: add virtio commands,
Dr. David Alan Gilbert <=
- Re: [RFC 0/5] hmp, qmp: Add some commands to introspect virtio devices, Marc-André Lureau, 2020/04/02