From nobody Sun Apr 28 20:53:25 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507035049133645.6236541345492; Tue, 3 Oct 2017 05:50:49 -0700 (PDT) Received: from localhost ([::1]:58449 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dzMeu-0006wZ-DQ for importer@patchew.org; Tue, 03 Oct 2017 08:50:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51601) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dzMcN-0005QN-Ts for qemu-devel@nongnu.org; Tue, 03 Oct 2017 08:48:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dzMcI-0000bp-R7 for qemu-devel@nongnu.org; Tue, 03 Oct 2017 08:48:11 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:19686 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dzMcB-0000H8-0v; Tue, 03 Oct 2017 08:47:59 -0400 Received: from work.sw.ru. (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v93Cln2B003268; Tue, 3 Oct 2017 15:47:54 +0300 (MSK) From: Jan Dakinevich To: qemu-devel@nongnu.org Date: Tue, 3 Oct 2017 15:47:40 +0300 Message-Id: <1507034861-4661-2-git-send-email-jan.dakinevich@virtuozzo.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1507034861-4661-1-git-send-email-jan.dakinevich@virtuozzo.com> References: <1507034861-4661-1-git-send-email-jan.dakinevich@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v4 1/2] virtio: introduce `query-virtio' QMP command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , "Denis V. Lunev" , qemu-block@nongnu.org, Amit Shah , Markus Armbruster , Jason Wang , Cornelia Huck , "Dr. David Alan Gilbert" , Max Reitz , Jan Dakinevich , "Michael S. Tsirkin" , Stefan Hajnoczi , Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The command is intended for gathering virtio information such as status, feature bits, negotiation status. It is convenient and useful for debug purpose. The commands returns generic virtio information for virtio such as common feature names and status bits names and information for all attached to current machine devices. To retrieve names of device-specific features `get_feature_name' callback in VirtioDeviceClass also was introduced. Cc: Denis V. Lunev Signed-off-by: Jan Dakinevich --- hw/block/virtio-blk.c | 21 +++++++++ hw/char/virtio-serial-bus.c | 15 +++++++ hw/display/virtio-gpu.c | 13 ++++++ hw/net/virtio-net.c | 35 +++++++++++++++ hw/scsi/virtio-scsi.c | 16 +++++++ hw/virtio/Makefile.objs | 2 + hw/virtio/virtio-balloon.c | 15 +++++++ hw/virtio/virtio-stub.c | 9 ++++ hw/virtio/virtio.c | 101 ++++++++++++++++++++++++++++++++++++++++= ++++ include/hw/virtio/virtio.h | 2 + qapi-schema.json | 1 + qapi/virtio.json | 94 +++++++++++++++++++++++++++++++++++++++++ 12 files changed, 324 insertions(+) create mode 100644 hw/virtio/virtio-stub.c create mode 100644 qapi/virtio.json diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 05d1440..c77f651 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -1017,6 +1017,26 @@ static Property virtio_blk_properties[] =3D { DEFINE_PROP_END_OF_LIST(), }; =20 +static const char *virtio_blk_get_feature_name(VirtIODevice *vdev, + unsigned feature) +{ + static const char *names[] =3D { + [VIRTIO_BLK_F_BARRIER] =3D "barrier", + [VIRTIO_BLK_F_SIZE_MAX] =3D "size_max", + [VIRTIO_BLK_F_SEG_MAX] =3D "seg_max", + [VIRTIO_BLK_F_RO] =3D "ro", + [VIRTIO_BLK_F_BLK_SIZE] =3D "blk_size", + [VIRTIO_BLK_F_SCSI] =3D "scsi", + [VIRTIO_BLK_F_TOPOLOGY] =3D "topology", + [VIRTIO_BLK_F_FLUSH] =3D "flush", + [VIRTIO_BLK_F_MQ] =3D "mq", + }; + if (feature >=3D ARRAY_SIZE(names)) { + return NULL; + } + return names[feature]; +} + static void virtio_blk_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); @@ -1030,6 +1050,7 @@ static void virtio_blk_class_init(ObjectClass *klass,= void *data) vdc->get_config =3D virtio_blk_update_config; vdc->set_config =3D virtio_blk_set_config; vdc->get_features =3D virtio_blk_get_features; + vdc->get_feature_name =3D virtio_blk_get_feature_name; vdc->set_status =3D virtio_blk_set_status; vdc->reset =3D virtio_blk_reset; vdc->save =3D virtio_blk_save_device; diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index 9470bd7..41f4466 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -1156,6 +1156,20 @@ static Property virtio_serial_properties[] =3D { DEFINE_PROP_END_OF_LIST(), }; =20 +static const char *virtio_serial_get_feature_name(VirtIODevice *vdev, + unsigned feature) +{ + static const char *names[] =3D { + [VIRTIO_CONSOLE_F_SIZE] =3D "size", + [VIRTIO_CONSOLE_F_MULTIPORT] =3D "multiport", + [VIRTIO_CONSOLE_F_EMERG_WRITE] =3D "emerg_write", + }; + if (feature >=3D ARRAY_SIZE(names)) { + return NULL; + } + return names[feature]; +} + static void virtio_serial_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); @@ -1170,6 +1184,7 @@ static void virtio_serial_class_init(ObjectClass *kla= ss, void *data) vdc->realize =3D virtio_serial_device_realize; vdc->unrealize =3D virtio_serial_device_unrealize; vdc->get_features =3D get_features; + vdc->get_feature_name =3D virtio_serial_get_feature_name; vdc->get_config =3D get_config; vdc->set_config =3D set_config; vdc->set_status =3D set_status; diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 3a8f1e1..49aa214 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -1307,6 +1307,18 @@ static Property virtio_gpu_properties[] =3D { DEFINE_PROP_END_OF_LIST(), }; =20 +static const char *virtio_gpu_get_feature_name(VirtIODevice *vdev, + unsigned feature) +{ + static const char *names[] =3D { + [VIRTIO_GPU_F_VIRGL] =3D "virgl", + }; + if (feature >=3D ARRAY_SIZE(names)) { + return NULL; + } + return names[feature]; +} + static void virtio_gpu_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); @@ -1317,6 +1329,7 @@ static void virtio_gpu_class_init(ObjectClass *klass,= void *data) vdc->get_config =3D virtio_gpu_get_config; vdc->set_config =3D virtio_gpu_set_config; vdc->get_features =3D virtio_gpu_get_features; + vdc->get_feature_name =3D virtio_gpu_get_feature_name; vdc->set_features =3D virtio_gpu_set_features; =20 vdc->reset =3D virtio_gpu_reset; diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 148071a..f4d20a85 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -2154,6 +2154,40 @@ static Property virtio_net_properties[] =3D { DEFINE_PROP_END_OF_LIST(), }; =20 +static const char *virtio_net_get_feature_name(VirtIODevice *vdev, + unsigned feature) +{ + static const char *names[] =3D { + [VIRTIO_NET_F_CSUM] =3D "csum", + [VIRTIO_NET_F_GUEST_CSUM] =3D "guest_csum", + [VIRTIO_NET_F_CTRL_GUEST_OFFLOADS] =3D "ctrl_guest_offloads", + [VIRTIO_NET_F_MTU] =3D "mtu", + [VIRTIO_NET_F_MAC] =3D "mac", + [VIRTIO_NET_F_GSO] =3D "gso", + [VIRTIO_NET_F_GUEST_TSO4] =3D "guest_tso4", + [VIRTIO_NET_F_GUEST_TSO6] =3D "guest_tso6", + [VIRTIO_NET_F_GUEST_ECN] =3D "guest_ecn", + [VIRTIO_NET_F_GUEST_UFO] =3D "guest_ufo", + [VIRTIO_NET_F_HOST_TSO4] =3D "host_tso4", + [VIRTIO_NET_F_HOST_TSO6] =3D "host_tso6", + [VIRTIO_NET_F_HOST_ECN] =3D "host_ecn", + [VIRTIO_NET_F_HOST_UFO] =3D "host_ufo", + [VIRTIO_NET_F_MRG_RXBUF] =3D "mrg_rxbuf", + [VIRTIO_NET_F_STATUS] =3D "status", + [VIRTIO_NET_F_CTRL_VQ] =3D "ctrl_vq", + [VIRTIO_NET_F_CTRL_RX] =3D "ctrl_rx", + [VIRTIO_NET_F_CTRL_VLAN] =3D "ctrl_vlan", + [VIRTIO_NET_F_CTRL_RX_EXTRA] =3D "ctrl_rx_extra", + [VIRTIO_NET_F_GUEST_ANNOUNCE] =3D "guest_announce", + [VIRTIO_NET_F_MQ] =3D "mq", + [VIRTIO_NET_F_CTRL_MAC_ADDR] =3D "ctrl_mac_addr", + }; + if (feature >=3D ARRAY_SIZE(names)) { + return NULL; + } + return names[feature]; +} + static void virtio_net_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); @@ -2169,6 +2203,7 @@ static void virtio_net_class_init(ObjectClass *klass,= void *data) vdc->get_features =3D virtio_net_get_features; vdc->set_features =3D virtio_net_set_features; vdc->bad_features =3D virtio_net_bad_features; + vdc->get_feature_name =3D virtio_net_get_feature_name; vdc->reset =3D virtio_net_reset; vdc->set_status =3D virtio_net_set_status; vdc->guest_notifier_mask =3D virtio_net_guest_notifier_mask; diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 3aa9971..b53cf8b 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -942,6 +942,21 @@ static const VMStateDescription vmstate_virtio_scsi = =3D { }, }; =20 +static const char *virtio_scsi_get_feature_name(VirtIODevice *vdev, + unsigned feature) +{ + static const char *names[] =3D { + [VIRTIO_SCSI_F_INOUT] =3D "inout", + [VIRTIO_SCSI_F_HOTPLUG] =3D "hotplug", + [VIRTIO_SCSI_F_CHANGE] =3D "change", + [VIRTIO_SCSI_F_T10_PI] =3D "t10_pi", + }; + if (feature >=3D ARRAY_SIZE(names)) { + return NULL; + } + return names[feature]; +} + static void virtio_scsi_common_class_init(ObjectClass *klass, void *data) { VirtioDeviceClass *vdc =3D VIRTIO_DEVICE_CLASS(klass); @@ -964,6 +979,7 @@ static void virtio_scsi_class_init(ObjectClass *klass, = void *data) vdc->unrealize =3D virtio_scsi_device_unrealize; vdc->set_config =3D virtio_scsi_set_config; vdc->get_features =3D virtio_scsi_get_features; + vdc->get_feature_name =3D virtio_scsi_get_feature_name; vdc->reset =3D virtio_scsi_reset; vdc->start_ioeventfd =3D virtio_scsi_dataplane_start; vdc->stop_ioeventfd =3D virtio_scsi_dataplane_stop; diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs index 765d363..73f3527 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -9,6 +9,8 @@ obj-$(CONFIG_LINUX) +=3D vhost.o vhost-backend.o vhost-user= .o obj-$(CONFIG_VHOST_VSOCK) +=3D vhost-vsock.o obj-y +=3D virtio-crypto.o obj-$(CONFIG_VIRTIO_PCI) +=3D virtio-crypto-pci.o +else +obj-y +=3D virtio-stub.o endif =20 common-obj-$(call lnot,$(CONFIG_LINUX)) +=3D vhost-stub.o diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 37cde38..b396eb1 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -509,6 +509,20 @@ static Property virtio_balloon_properties[] =3D { DEFINE_PROP_END_OF_LIST(), }; =20 +static const char *virtio_balloon_get_feature_name(VirtIODevice *vdev, + unsigned feature) +{ + static const char *names[] =3D { + [VIRTIO_BALLOON_F_MUST_TELL_HOST] =3D "must_tell_host", + [VIRTIO_BALLOON_F_STATS_VQ] =3D "stats_vq", + [VIRTIO_BALLOON_F_DEFLATE_ON_OOM] =3D "deflate_on_oom", + }; + if (feature >=3D ARRAY_SIZE(names)) { + return NULL; + } + return names[feature]; +} + static void virtio_balloon_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); @@ -523,6 +537,7 @@ static void virtio_balloon_class_init(ObjectClass *klas= s, void *data) vdc->get_config =3D virtio_balloon_get_config; vdc->set_config =3D virtio_balloon_set_config; vdc->get_features =3D virtio_balloon_get_features; + vdc->get_feature_name =3D virtio_balloon_get_feature_name; vdc->set_status =3D virtio_balloon_set_status; vdc->vmsd =3D &vmstate_virtio_balloon_device; } diff --git a/hw/virtio/virtio-stub.c b/hw/virtio/virtio-stub.c new file mode 100644 index 0000000..51a99de --- /dev/null +++ b/hw/virtio/virtio-stub.c @@ -0,0 +1,9 @@ +#include "qemu/osdep.h" +#include "qmp-commands.h" +#include "qapi/qmp/qerror.h" + +VirtioInfo *qmp_query_virtio(Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 3129d25..f182aa7 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -13,6 +13,7 @@ =20 #include "qemu/osdep.h" #include "qapi/error.h" +#include "qmp-commands.h" #include "qemu-common.h" #include "cpu.h" #include "trace.h" @@ -2665,6 +2666,106 @@ bool virtio_device_ioeventfd_enabled(VirtIODevice *= vdev) return virtio_bus_ioeventfd_enabled(vbus); } =20 +static void virtio_info_bit_list_add(VirtioInfoBitList **list, unsigned bi= t, + const char *name) +{ + VirtioInfoBitList *info =3D g_new0(VirtioInfoBitList, 1); + + info->next =3D *list; + *list =3D info; + + info->value =3D g_new0(VirtioInfoBit, 1); + info->value->bit =3D bit; + info->value->name =3D g_strdup(name); +} + +static void virtio_info_device_list_add(VirtioInfoDeviceList **list, + VirtIODevice *vdev) +{ + VirtioDeviceClass *vdc =3D VIRTIO_DEVICE_GET_CLASS(vdev); + VirtioInfoDeviceList *device; + unsigned idx; + + device =3D g_new0(VirtioInfoDeviceList, 1); + device->value =3D g_new0(VirtioInfoDevice, 1); + device->next =3D *list; + + *list =3D device; + + device->value->qom_path =3D object_get_canonical_path(OBJECT(vdev)); + device->value->host_features =3D vdev->host_features; + device->value->guest_features =3D vdev->guest_features; + device->value->status =3D vdev->status; + + if (!vdc->get_feature_name) { + return; + } + + for (idx =3D 64; idx--; ) { + const char *name =3D vdc->get_feature_name(vdev, idx); + if (!name) { + continue; + } + virtio_info_bit_list_add(&device->value->feature_names, idx, name); + } +} + +static void qmp_query_virtio_recursive(VirtioInfo *info, BusState *bus) +{ + BusChild *kid; + + QTAILQ_FOREACH(kid, &bus->children, sibling) { + DeviceState *dev =3D kid->child; + BusState *child; + + if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_DEVICE)) { + virtio_info_device_list_add(&info->devices, VIRTIO_DEVICE(dev)= ); + } + QLIST_FOREACH(child, &dev->child_bus, sibling) { + qmp_query_virtio_recursive(info, child); + } + } +} + +VirtioInfo *qmp_query_virtio(Error **errp) +{ + BusState *bus =3D sysbus_get_default(); + VirtioInfo *info =3D g_new0(VirtioInfo, 1); + + /* Common features */ + virtio_info_bit_list_add(&info->feature_names, VIRTIO_F_IOMMU_PLATFORM, + "iommu_platform"); + virtio_info_bit_list_add(&info->feature_names, VIRTIO_F_VERSION_1, + "version_1"); + virtio_info_bit_list_add(&info->feature_names, VIRTIO_RING_F_EVENT_IDX, + "event_idx"); + virtio_info_bit_list_add(&info->feature_names, VIRTIO_RING_F_INDIRECT_= DESC, + "indirect_desc"); + virtio_info_bit_list_add(&info->feature_names, VIRTIO_F_ANY_LAYOUT, + "any_layout"); + virtio_info_bit_list_add(&info->feature_names, VIRTIO_F_NOTIFY_ON_EMPT= Y, + "notify_on_empty"); + + /* Status bits */ + virtio_info_bit_list_add(&info->status_names, 7 /* VIRTIO_CONFIG_S_FAI= LED */, + "failed"); + virtio_info_bit_list_add(&info->status_names, 6 /* VIRTIO_CONFIG_S_NEE= DS_RESET */, + "needs_reset"); + virtio_info_bit_list_add(&info->status_names, 3 /* VIRTIO_CONFIG_S_FEA= TURES_OK */, + "features_ok"); + virtio_info_bit_list_add(&info->status_names, 2 /* VIRTIO_CONFIG_S_DRI= VER_OK */, + "driver_ok"); + virtio_info_bit_list_add(&info->status_names, 1 /* VIRTIO_CONFIG_S_DRI= VER */, + "driver"); + virtio_info_bit_list_add(&info->status_names, 0 /* VIRTIO_CONFIG_S_ACK= NOWLEDGE */, + "acknowledge"); + + if (bus) { + qmp_query_virtio_recursive(info, bus); + } + return info; +} + static const TypeInfo virtio_device_info =3D { .name =3D TYPE_VIRTIO_DEVICE, .parent =3D TYPE_DEVICE, diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 80c45c3..3ea2cd0 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -141,6 +141,8 @@ typedef struct VirtioDeviceClass { void (*save)(VirtIODevice *vdev, QEMUFile *f); int (*load)(VirtIODevice *vdev, QEMUFile *f, int version_id); const VMStateDescription *vmsd; + /* Get the name of device specific feature */ + const char *(*get_feature_name)(VirtIODevice *vdev, unsigned feature); } VirtioDeviceClass; =20 void virtio_instance_init_common(Object *proxy_obj, void *data, diff --git a/qapi-schema.json b/qapi-schema.json index a3ba1c9..78762b1 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -92,6 +92,7 @@ { 'include': 'qapi/transaction.json' } { 'include': 'qapi/trace.json' } { 'include': 'qapi/introspect.json' } +{ 'include': 'qapi/virtio.json' } =20 ## # =3D Miscellanea diff --git a/qapi/virtio.json b/qapi/virtio.json new file mode 100644 index 0000000..b8b52ac --- /dev/null +++ b/qapi/virtio.json @@ -0,0 +1,94 @@ +# -*- Mode: Python -*- +# + +## +# =3D Virtio devices +## + +{ 'include': 'common.json' } + +## +# @VirtioInfoBit: +# +# Named virtio bit +# +# @bit: bit number +# +# @name: bit name +# +# Since: 2.11.0 +# +## +{ + 'struct': 'VirtioInfoBit', + 'data': { + 'bit': 'uint64', + 'name': 'str' + } +} + +## +# @VirtioInfoDevice: +# +# Information about specific virtio device +# +# @qom_path: QOM path of the device +# +# @feature-names: names of device-specific features +# +# @host-features: bitmask of features, provided by devices +# +# @guest-features: bitmask of features, acknowledged by guest +# +# @status: virtio device status bitmask +# +# Since: 2.11.0 +# +## +{ + 'struct': 'VirtioInfoDevice', + 'data': { + 'qom_path': 'str', + 'feature-names': ['VirtioInfoBit'], + 'host-features': 'uint64', + 'guest-features': 'uint64', + 'status': 'uint64' + } +} + +## +# @VirtioInfo: +# +# Information about virtio devices +# +# @feature-names: names of common virtio features +# +# @status-names: names of bits which represents virtio device status +# +# @devices: list of per-device virtio information +# +# Since: 2.11.0 +# +## +{ + 'struct': 'VirtioInfo', + 'data': { + 'feature-names': ['VirtioInfoBit'], + 'status-names': ['VirtioInfoBit'], + 'devices': ['VirtioInfoDevice'] + } +} + + +## +# @query-virtio: +# +# Returns generic and per-device virtio information +# +# Since: 2.11.0 +# +## +{ + 'command': 'query-virtio', + 'returns': 'VirtioInfo' +} --=20 2.1.4 From nobody Sun Apr 28 20:53:25 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507034973157500.89074966075987; Tue, 3 Oct 2017 05:49:33 -0700 (PDT) Received: from localhost ([::1]:58439 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dzMda-00060O-4o for importer@patchew.org; Tue, 03 Oct 2017 08:49:26 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51472) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dzMcD-0005Ke-NO for qemu-devel@nongnu.org; Tue, 03 Oct 2017 08:48:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dzMcC-0000Nc-1f for qemu-devel@nongnu.org; Tue, 03 Oct 2017 08:48:01 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:19160 helo=relay.sw.ru) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dzMcB-0000Iz-LI for qemu-devel@nongnu.org; Tue, 03 Oct 2017 08:47:59 -0400 Received: from work.sw.ru. (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v93Cln2C003268; Tue, 3 Oct 2017 15:47:55 +0300 (MSK) From: Jan Dakinevich To: qemu-devel@nongnu.org Date: Tue, 3 Oct 2017 15:47:41 +0300 Message-Id: <1507034861-4661-3-git-send-email-jan.dakinevich@virtuozzo.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1507034861-4661-1-git-send-email-jan.dakinevich@virtuozzo.com> References: <1507034861-4661-1-git-send-email-jan.dakinevich@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x [fuzzy] X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH v4 2/2] virtio: add `info virtio' HMP command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , "Denis V. Lunev" , Amit Shah , Markus Armbruster , Jason Wang , Cornelia Huck , "Dr. David Alan Gilbert" , Max Reitz , Jan Dakinevich , Stefan Hajnoczi , Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The command prints data from `query-virtio' QMP in human-readable format. Cc: Denis V. Lunev Signed-off-by: Jan Dakinevich --- hmp-commands-info.hx | 14 ++++++++++ hmp.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++= ++++ hmp.h | 1 + 3 files changed, 94 insertions(+) diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 4f1ece9..2550027 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -868,6 +868,20 @@ ETEXI }, =20 STEXI +@item info virtio +@findex virtio +Display guest and host fetures for all virtio devices. +ETEXI + + { + .name =3D "virtio", + .args_type =3D "", + .params =3D "", + .help =3D "show virtio info", + .cmd =3D hmp_info_virtio, + }, + +STEXI @end table ETEXI =20 diff --git a/hmp.c b/hmp.c index ace729d..c4dd280 100644 --- a/hmp.c +++ b/hmp.c @@ -43,6 +43,7 @@ #include "hw/intc/intc.h" #include "migration/snapshot.h" #include "migration/misc.h" +#include "hw/virtio/virtio.h" =20 #ifdef CONFIG_SPICE #include @@ -2894,3 +2895,81 @@ void hmp_info_memory_size_summary(Monitor *mon, cons= t QDict *qdict) } hmp_handle_error(mon, &err); } + +#define HMP_INFO_VIRTIO_INDENT 2 +#define HMP_INFO_VIRTIO_FIELD 32 + +static void hmp_info_virtio_print_status(Monitor *mon, VirtioInfo *info, + VirtioInfoDevice *device) +{ + VirtioInfoBitList *lbit; + const char *comma =3D ""; + + for (lbit =3D info->status_names; lbit; lbit =3D lbit->next) { + if (!(device->status & (1ull << lbit->value->bit))) { + continue; + } + monitor_printf(mon, "%s%s", comma, lbit->value->name); + comma =3D ","; + } + monitor_printf(mon, "\n"); +} + +static void hmp_info_virtio_print_features(Monitor *mon, + VirtioInfoBitList *list, + VirtioInfoDevice *device) +{ + VirtioInfoBitList *lbit; + + for (lbit =3D list; lbit; lbit =3D lbit->next) { + const char *ack =3D virtio_has_feature(device->guest_features, + lbit->value->bit) ? "acked" := ""; + if (!virtio_has_feature(device->host_features, lbit->value->bit)) { + continue; + } + monitor_printf(mon, "%*s%*s%*s\n", HMP_INFO_VIRTIO_INDENT, "", + HMP_INFO_VIRTIO_FIELD, lbit->value->name, + HMP_INFO_VIRTIO_FIELD, ack); + } +} + +static void hmp_info_virtio_print(Monitor *mon, VirtioInfo *info, + VirtioInfoDevice *device) +{ + Object *obj =3D object_resolve_path(device->qom_path, NULL); + char *path =3D qdev_get_dev_path(DEVICE(obj)); + + monitor_printf(mon, "%s at %s\n", object_get_typename(obj), path); + g_free(path); + + monitor_printf(mon, "%*sstatus: 0x%02"PRIx64" ", + HMP_INFO_VIRTIO_INDENT, "", device->status); + hmp_info_virtio_print_status(mon, info, device); + + monitor_printf(mon, "%*shost features: 0x%016"PRIx64"\n", + HMP_INFO_VIRTIO_INDENT, "", device->host_features); + monitor_printf(mon, "%*sguest features: 0x%016"PRIx64"\n", + HMP_INFO_VIRTIO_INDENT, "", device->guest_features); + + monitor_printf(mon, "%*scommon features:\n", HMP_INFO_VIRTIO_INDENT, "= "); + hmp_info_virtio_print_features(mon, info->feature_names, device); + + monitor_printf(mon, "%*sspecific features:\n", HMP_INFO_VIRTIO_INDENT,= ""); + hmp_info_virtio_print_features(mon, device->feature_names, device); +} + +void hmp_info_virtio(Monitor *mon, const QDict *qdict) +{ + Error *err =3D NULL; + VirtioInfo *info; + VirtioInfoDeviceList *ldevice; + + info =3D qmp_query_virtio(&err); + if (err) { + return; + } + + for (ldevice =3D info->devices; ldevice; ldevice =3D ldevice->next) { + hmp_info_virtio_print(mon, info, ldevice->value); + } +} diff --git a/hmp.h b/hmp.h index 3605003..3e8f30a 100644 --- a/hmp.h +++ b/hmp.h @@ -146,5 +146,6 @@ void hmp_info_ramblock(Monitor *mon, const QDict *qdict= ); void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict); void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict); void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict); +void hmp_info_virtio(Monitor *mon, const QDict *qdict); =20 #endif --=20 2.1.4