Re: [Qemu-block] [Qemu-devel] [RFC v6 1/2] virtio: introduce `query-virtio' QMP command

2017-12-19 Thread Jan Dakinevich
On Tue, 19 Dec 2017 15:57:18 +0100
Markus Armbruster  wrote:

> QAPI/QMP interface review only.
> 
> You neglected to cc: the maintainers of qapi-schema.json, so I'm doing
> that for you.
> 

Thank you so much. I screwed up with this patchset at least twice: with
list of maintainers and with my own e-mail.

> Jan Dakinevich  writes:
> 
> > 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 `tell_feature_name'
> > callback in VirtioDeviceClass also was introduced.
> >
> > Cc: Denis V. Lunev 
> > Signed-off-by: Jan Dakinevich 
> [...]
> > diff --git a/qapi-schema.json b/qapi-schema.json
> > index 1845795..51cd0f3 100644
> > --- a/qapi-schema.json
> > +++ b/qapi-schema.json
> > @@ -3200,3 +3200,73 @@
> >  # Since: 2.11
> >  ##
> >  { 'command': 'watchdog-set-action', 'data' : {'action':
> > 'WatchdogAction'} } +
> > +##
> > +# @VirtioFeature:
> > +#
> > +# Virtio feature bit with negotiation status
> > +#
> > +# @name: name of feature bit
> > +#
> > +# @acked: negotiation status, `true' if guest acknowledged the
> > feature +#
> > +# Since: 2.12
> > +##
> > +{
> > +'struct': 'VirtioFeature',
> > +'data': {
> > +'name': 'str',
> > +'acked': 'bool'
> > +}
> > +}
> > +
> > +##
> > +# @VirtioInfo:
> > +#
> > +# Information about virtio device
> > +#
> > +# @qom-path: QOM path of the device
> > +#
> > +# @status: status bitmask
> > +#
> > +# @host-features: bitmask of features, exposed by device
> > +#
> > +# @guest-features: bitmask of features, acknowledged by guest
> 
> Quoting my review of v4: "Unsigned integer interpreted as combination
> of well-known bit-valued symbols" is a fine C interface, but a pretty
> horrid QMP interface.  What's wrong with doing a set the
> straightforward way as "array of enum"?  As far as I can see, I
> didn't get a reply back then.  You'll have to give one to get the
> patch accepted.
> 

Most probably, I didn't understand you last time. Although, I'm still
far from correct understanding.

About 'array of enum', I could make the following description:

{
  'enum': 'VirtioFeatureScsiBit',
  'data': ['inout', 'hotplug', 'change', 'ta10_pi']
}

{
  'struct': 'VirtioFeatureScsi',
  'data' : {
  'bit': 'VirtioFeatureScsiBit',
  'acked': 'bool'
  }
}

{
  'enum': 'VirtioFeatureSerialBit',
  'data': ['size', 'multiport', 'emerg-write']
}

{
  'struct': 'VirtioFeatureSerial',
  'data' : {
  'bit': 'VirtioFeatureSerialBit',
  'acked': 'bool'
  }
}

{ 
  'enum': 'VirtioFeatureCategory',
  'data': ['scsi', 'serial'] 
}

{
  'union': 'VirtioFeature',
  'base': {
'category': 'VirtioFeatureCategory'
  },
  'discriminator': 'categoty',
  'data': {
'scsi': 'VirtioFeatureScsi',
'serial': 'VirtioFeatureSerial'
  }
}

{
  'union': 'VirtioInfo',
  'data': {
'qom-path': 'str',
'device-features': ['VirtioFeature']
...
  }
}

But IMO, it only increases complexity without any benefit. To use this
description, at first it should be listed all features names in enums.
Then, these enums should be mapped into bit numbers and differently for
each virtio device. I expect something like this:

VirtioFeatureScsiBit bit = ...

switch (bit) {
case VIRTIO_FEATURE_SCSI_BIT_INOUT:
return VIRTIO_SCSI_F_INOUT;
case VIRTIO_FEATURE_SERIAL_BIT_HOTPLUG:
return VIRTIO_SCSI_F_HOTPLUG;
case VIRTIO_FEATURE_SERIAL_BIT_CHANGE:
return VIRTIO_SCSI_F_CHANGE;
case VIRTIO_FEATURE_SERIAL_BIT_T10_PI:
return VIRTIO_SCSI_F_T10_PI;
}

So, boilerplate for mapping between bit numbers and and theirs names
will not go away.

Furthermore, HMP command should produc

[Qemu-block] [Qemu-devel] [RFC v6 2/2] virtio: add `info virtio' HMP command

2017-12-17 Thread Jan Dakinevich
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| 74 
 hmp.h|  1 +
 3 files changed, 89 insertions(+)

diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 54c3e5e..292280a 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -868,6 +868,20 @@ enabled) memory in bytes.
 ETEXI
 
 STEXI
+@item info virtio
+@findex virtio
+Display guest and host fetures for all virtio devices.
+ETEXI
+
+{
+.name   = "virtio",
+.args_type  = "path:s?",
+.params = "[path]",
+.help   = "show virtio info",
+.cmd= hmp_info_virtio,
+},
+
+STEXI
 @end table
 ETEXI
 
diff --git a/hmp.c b/hmp.c
index 35a7041..786782b 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"
 
 #ifdef CONFIG_SPICE
 #include 
@@ -2918,3 +2919,76 @@ void hmp_info_memory_size_summary(Monitor *mon, const 
QDict *qdict)
 }
 hmp_handle_error(mon, &err);
 }
+
+#define HMP_INFO_VIRTIO_INDENT 2
+#define HMP_INFO_VIRTIO_FEATURE 40
+
+static void hmp_info_virtio_print(Monitor *mon, VirtioInfo *info)
+{
+Object *obj = object_resolve_path(info->qom_path, NULL);
+char *path = qdev_get_dev_path(DEVICE(obj));
+VirtioFeatureList *feat;
+strList *status;
+
+monitor_printf(mon, "%s at %s\n", object_get_typename(obj), path);
+g_free(path);
+
+monitor_printf(mon, "%*sQOM path: %s\n",
+   HMP_INFO_VIRTIO_INDENT, "", info->qom_path);
+
+/* device status */
+monitor_printf(mon, "%*sstatus: 0x%02"PRIx8"\n",
+   HMP_INFO_VIRTIO_INDENT, "", info->status);
+for (status = info->status_names; status; status = status->next) {
+monitor_printf(mon, "%*s%s\n",
+   HMP_INFO_VIRTIO_INDENT * 2, "", status->value);
+}
+
+
+/* host and guest feature */
+monitor_printf(mon, "%*shost features:  0x%016"PRIx64"\n",
+   HMP_INFO_VIRTIO_INDENT, "", info->host_features);
+monitor_printf(mon, "%*sguest features: 0x%016"PRIx64"\n",
+   HMP_INFO_VIRTIO_INDENT, "", info->guest_features);
+
+/* common features */
+monitor_printf(mon, "%*scommon features:%s\n",
+   HMP_INFO_VIRTIO_INDENT, "",
+   info->common_features_names ? "" : " (none)");
+for (feat = info->common_features_names; feat; feat = feat->next) {
+monitor_printf(mon, "%*s%-*s%s\n",
+   HMP_INFO_VIRTIO_INDENT * 2, "",
+   HMP_INFO_VIRTIO_FEATURE, feat->value->name,
+   feat->value->acked ? " acked" : "");
+}
+
+/* device features */
+monitor_printf(mon, "%*sdevice features:%s\n",
+   HMP_INFO_VIRTIO_INDENT, "",
+   info->device_features_names ? "" : " (none)");
+for (feat = info->device_features_names; feat; feat = feat->next) {
+monitor_printf(mon, "%*s%-*s%s\n",
+   HMP_INFO_VIRTIO_INDENT * 2, "",
+   HMP_INFO_VIRTIO_FEATURE, feat->value->name,
+   feat->value->acked ? " acked" : "");
+}
+}
+
+void hmp_info_virtio(Monitor *mon, const QDict *qdict)
+{
+const char *path = qdict_get_try_str(qdict, "path");
+Error *err = NULL;
+VirtioInfoList *head, *info;
+
+
+head = qmp_query_virtio(!!path, path, &err);
+if (err) {
+return;
+}
+
+for (info = head; info; info = info->next) {
+hmp_info_virtio_print(mon, info->value);
+}
+
+qapi_free_VirtioInfoList(head);
+}
diff --git a/hmp.h b/hmp.h
index a6f56b1..156293e 100644
--- a/hmp.h
+++ b/hmp.h
@@ -147,5 +147,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);
 
 #endif
-- 
2.1.4




[Qemu-block] [Qemu-devel] [RFC v6 1/2] virtio: introduce `query-virtio' QMP command

2017-12-17 Thread Jan Dakinevich
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 `tell_feature_name'
callback in VirtioDeviceClass also was introduced.

Cc: Denis V. Lunev 
Signed-off-by: Jan Dakinevich 
---
 hw/block/virtio-blk.c   |  20 +++
 hw/char/virtio-serial-bus.c |  14 +
 hw/display/virtio-gpu.c |  12 
 hw/net/virtio-net.c |  34 +++
 hw/scsi/virtio-scsi.c   |  15 +
 hw/virtio/Makefile.objs |   3 +
 hw/virtio/virtio-balloon.c  |  14 +
 hw/virtio/virtio-qmp.c  | 134 
 hw/virtio/virtio-stub.c |   9 +++
 hw/virtio/virtio.c  |  41 ++
 include/hw/virtio/virtio.h  |   6 ++
 qapi-schema.json|  70 +++
 12 files changed, 372 insertions(+)
 create mode 100644 hw/virtio/virtio-qmp.c
 create mode 100644 hw/virtio/virtio-stub.c

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 05d1440..2ffd949 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1017,6 +1017,25 @@ static Property virtio_blk_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static const char *virtio_blk_tell_feature_name(VirtIODevice *vdev,
+unsigned fbit)
+{
+#define FBIT(fbit) case fbit: return #fbit
+switch (fbit) {
+FBIT(VIRTIO_BLK_F_BARRIER);
+FBIT(VIRTIO_BLK_F_SIZE_MAX);
+FBIT(VIRTIO_BLK_F_SEG_MAX);
+FBIT(VIRTIO_BLK_F_RO);
+FBIT(VIRTIO_BLK_F_BLK_SIZE);
+FBIT(VIRTIO_BLK_F_SCSI);
+FBIT(VIRTIO_BLK_F_TOPOLOGY);
+FBIT(VIRTIO_BLK_F_FLUSH);
+FBIT(VIRTIO_BLK_F_MQ);
+}
+#undef FBIT
+return NULL;
+}
+
 static void virtio_blk_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1030,6 +1049,7 @@ static void virtio_blk_class_init(ObjectClass *klass, 
void *data)
 vdc->get_config = virtio_blk_update_config;
 vdc->set_config = virtio_blk_set_config;
 vdc->get_features = virtio_blk_get_features;
+vdc->tell_feature_name = virtio_blk_tell_feature_name;
 vdc->set_status = virtio_blk_set_status;
 vdc->reset = virtio_blk_reset;
 vdc->save = virtio_blk_save_device;
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 9470bd7..1d4678b 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -1156,6 +1156,19 @@ static Property virtio_serial_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static const char *virtio_serial_tell_feature_name(VirtIODevice *vdev,
+   unsigned fbit)
+{
+#define FBIT(fbit) case fbit: return #fbit
+switch (fbit) {
+FBIT(VIRTIO_CONSOLE_F_SIZE);
+FBIT(VIRTIO_CONSOLE_F_MULTIPORT);
+FBIT(VIRTIO_CONSOLE_F_EMERG_WRITE);
+};
+#undef FBIT
+return NULL;
+}
+
 static void virtio_serial_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1170,6 +1183,7 @@ static void virtio_serial_class_init(ObjectClass *klass, 
void *data)
 vdc->realize = virtio_serial_device_realize;
 vdc->unrealize = virtio_serial_device_unrealize;
 vdc->get_features = get_features;
+vdc->tell_feature_name = virtio_serial_tell_feature_name;
 vdc->get_config = get_config;
 vdc->set_config = set_config;
 vdc->set_status = set_status;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 274e365..1906b68 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1317,6 +1317,17 @@ static Property virtio_gpu_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static const char *virtio_gpu_tell_feature_name(VirtIODevice *vdev,
+unsigned fbit)
+{
+#define FBIT(fbit) case fbit: return #fbit
+switch (fbit) {
+FBIT(VIRTIO_GPU_F_VIRGL);
+};
+#undef FBIT
+return NULL;
+}
+
 static void virtio_gpu_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1327,6 +1338,7 @@ static void virtio_gpu_class_init(ObjectClass *klass, 
void *data)
 vdc->get_config = virtio_gpu_get_config;
 vdc->set_config = virtio_gpu_set_config;
 vdc->get_features = virtio_gpu_get_features;
+vdc->tell_feature_name = virtio_gpu_tell_feature_name;
 vdc->set_features = virtio_gpu_set_features;
 
 vdc->reset = virtio_gpu_reset;
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 38674b0..0fbd055 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -2163,6 +2163,39 @@ static Property virtio_net_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+s

[Qemu-block] [Qemu-devel] [RFC v6 0/2] virtio: introduce `info virtio' hmp command

2017-12-17 Thread Jan Dakinevich
From: Jan Dakinevich 

After some discussion, I am going to suggest reworked QMP/HMP for
gathering virtio info. It would provide the following monitor output.

(qemu) info virtio
virtio-blk-device at :00:02.0
  QOM path: /machine/peripheral-anon/device[0]/virtio-backend
  status: 0x0f
VIRTIO_CONFIG_S_ACKNOWLEDGE
VIRTIO_CONFIG_S_DRIVER
VIRTIO_CONFIG_S_DRIVER_OK
VIRTIO_CONFIG_S_FEATURES_OK
  host features:  0x000179000e54
  guest features: 0x00013e54
  common features:
VIRTIO_F_NOTIFY_ON_EMPTY
VIRTIO_F_ANY_LAYOUT
VIRTIO_RING_F_INDIRECT_DESC  acked
VIRTIO_RING_F_EVENT_IDX  acked
VIRTIO_F_BAD_FEATURE
VIRTIO_F_VERSION_1   acked
  device features:
VIRTIO_BLK_F_SEG_MAX acked
VIRTIO_BLK_F_BLK_SIZEacked
VIRTIO_BLK_F_FLUSH   acked
VIRTIO_BLK_F_TOPOLOGYacked

v5: http://lists.nongnu.org/archive/html/qemu-devel/2017-10/msg05667.html
v4: http://lists.nongnu.org/archive/html/qemu-devel/2017-10/msg00393.html
v3: http://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07565.html
v2: http://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07527.html
v1: http://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07247.html

Jan Dakinevich (2):
  virtio: introduce `query-virtio' QMP command
  virtio: add `info virtio' HMP command

 hmp-commands-info.hx|  14 +
 hmp.c   |  74 
 hmp.h   |   1 +
 hw/block/virtio-blk.c   |  20 +++
 hw/char/virtio-serial-bus.c |  14 +
 hw/display/virtio-gpu.c |  12 
 hw/net/virtio-net.c |  34 +++
 hw/scsi/virtio-scsi.c   |  15 +
 hw/virtio/Makefile.objs |   3 +
 hw/virtio/virtio-balloon.c  |  14 +
 hw/virtio/virtio-qmp.c  | 134 
 hw/virtio/virtio-stub.c |   9 +++
 hw/virtio/virtio.c  |  41 ++
 include/hw/virtio/virtio.h  |   6 ++
 qapi-schema.json|  70 +++
 15 files changed, 461 insertions(+)
 create mode 100644 hw/virtio/virtio-qmp.c
 create mode 100644 hw/virtio/virtio-stub.c

--
2.1.4




Re: [Qemu-block] [Qemu-devel] [PATCH v4 1/2] virtio: introduce `query-virtio' QMP command

2017-10-05 Thread Jan Dakinevich


On 10/04/2017 07:00 PM, Eric Blake wrote:
> On 10/04/2017 09:26 AM, Jan Dakinevich wrote:
> 
>>>>>> +{
>>>>>> +'struct': 'VirtioInfo',
>>>>>> +'data': {
>>>>>> +'feature-names': ['VirtioInfoBit'],
>>>>>
>>>>> Why is feature-names listed at two different nestings of the return value?
>>>>>
>>>>
>>>> These are different feature names. First names are common and predefined
>>>> for all devices. Second names are device-specific.
>>>
>>> If you can turn these into enums (union'd enums?) then you might
>>> be able to get rid of a lot of your array filling/naming conversion
>>> boilerplate. (Not sure if it's worth it, but it's worth looking).
>>>
>>
>> I would be happy to drop this boilerplate, but how enum could help here?
>> To respond my requirement it should be something like set, not enum.
>> Even so, having set, I would have been needed to declare mapping between
>> names in set type and bit numbers within feature bitmask.
> 
> Instead of returning a bitmask ("mask":123) as well as an array naming
> those bits
> ([{"bit":1,"name":"bit1"},{"bit":2","name":"bit2"},{"bit":4,"name":"bit4},...]),
> you could omit the bit numbers and just return an array of named bits
> (["bit1", "bit2", "bit4"]).  An enum lets you declare up front what
> named bits are supported (and code can introspect when new named bits
> are supported in newer qemu).
>
But how can I declare in this notation that name "bit1" is owned by bit
#1, name "bit2" is owned by bit #2, name "bit4" is owned by bit #4, and
all other bits has no names.

> Perhaps it's easier to first take a step back, and show what the desired
> output might be like, and then we can figure out how to represent that
> output in QAPI.
> 

Yeah... I expect the following HMP output:

(qmue) info virtio
virtio-blk-device at :00:07.0
  status:   0x07 acknowledge,driver,driver_ok
  host features:0x000179000e54
  guest features:   0x3e54
  common features:
   notify_on_empty
any_layout
 indirect_desc   acked
 event_idx   acked
 version_1
  specific features:
   seg_max   acked
  blk_size   acked
 flush   acked
  topology   acked
virtio-serial-device at :00:08.0
  status:   0x07 acknowledge,driver,driver_ok
  host features:0x00017906
  guest features:   0x3002
  common features:
   notify_on_empty
any_layout
 indirect_desc   acked
 event_idx   acked
 version_1
  specific features:
 multiport   acked
   emerg_write

-- 
Best regards
Jan Dakinevich



Re: [Qemu-block] [Qemu-devel] [PATCH v4 1/2] virtio: introduce `query-virtio' QMP command

2017-10-04 Thread Jan Dakinevich


On 10/03/2017 07:29 PM, Dr. David Alan Gilbert wrote:
> * Jan Dakinevich (jan.dakinev...@virtuozzo.com) wrote:
>>
>>
>> On 10/03/2017 05:02 PM, Eric Blake wrote:
>>> On 10/03/2017 07:47 AM, Jan Dakinevich wrote:
>>>> 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
>>>
>>> This creates a new .json file, but does not touch MAINTAINERS.  Our idea
>>> in splitting the .json files was to make it easier for each sub-file
>>> that needs a specific maintainer in addition to the overall *.json line
>>> for QAPI maintainers, so this may deserve a MAINTAINERS entry.
>>>
>>
>> Ok.
>>
>>>> +++ b/qapi/virtio.json
>>>> @@ -0,0 +1,94 @@
>>>> +# -*- Mode: Python -*-
>>>> +#
>>>> +
>>>> +##
>>>> +# = Virtio devices
>>>> +##
>>>> +
>>>> +{ 'include': 'common.json' }
>>>> +
>>>> +##
>>>> +# @VirtioInfoBit:
>>>> +#
>>>> +# Named virtio bit
>>>> +#
>>>> +# @bit: bit number
>>>> +#
>>>> +# @name: bit name
>>>> +#
>>>> +# Since: 2.11.0
>>>> +#
>>>> +##
>>>> +{
>>>> +'struct': 'VirtioInfoBit',
>>>> +'data': {
>>>> +'bit': 'uint64',
>>>
>>> Why is this a 64-bit value? Are the values 0-63, or are they 1, 2, 4, 8,
>>> ...?  The documentation on 'bit number' is rather sparse.
>>
>> I would prefer `uint' here, but I don't see generic unsigned type (may
>> be, I am mistaken). I could use uint8 here, though.
>>
>>>
>>>> +'name': 'str'
>>>
>>> Wouldn't an enum type be better than an open-ended string?
>>>
>>
>> Bit names are not known here, they are obtained from virtio device
>> implementations.
>>
>>>> +}
>>>> +}
>>>> +
>>>> +##
>>>> +# @VirtioInfoDevice:
>>>> +#
>>>> +# Information about specific virtio device
>>>> +#
>>>> +# @qom_path: QOM path of the device
>>>
>>> Please make this 'qom-path' - new interfaces should prefer '-' over '_'.
>>
>> Ok.
>>
>>>> +#
>>>> +# @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

Re: [Qemu-block] [Qemu-devel] [PATCH v4 1/2] virtio: introduce `query-virtio' QMP command

2017-10-03 Thread Jan Dakinevich


On 10/03/2017 05:02 PM, Eric Blake wrote:
> On 10/03/2017 07:47 AM, Jan Dakinevich wrote:
>> 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
> 
> This creates a new .json file, but does not touch MAINTAINERS.  Our idea
> in splitting the .json files was to make it easier for each sub-file
> that needs a specific maintainer in addition to the overall *.json line
> for QAPI maintainers, so this may deserve a MAINTAINERS entry.
> 

Ok.

>> +++ b/qapi/virtio.json
>> @@ -0,0 +1,94 @@
>> +# -*- Mode: Python -*-
>> +#
>> +
>> +##
>> +# = Virtio devices
>> +##
>> +
>> +{ 'include': 'common.json' }
>> +
>> +##
>> +# @VirtioInfoBit:
>> +#
>> +# Named virtio bit
>> +#
>> +# @bit: bit number
>> +#
>> +# @name: bit name
>> +#
>> +# Since: 2.11.0
>> +#
>> +##
>> +{
>> +'struct': 'VirtioInfoBit',
>> +'data': {
>> +'bit': 'uint64',
> 
> Why is this a 64-bit value? Are the values 0-63, or are they 1, 2, 4, 8,
> ...?  The documentation on 'bit number' is rather sparse.

I would prefer `uint' here, but I don't see generic unsigned type (may
be, I am mistaken). I could use uint8 here, though.

> 
>> +'name': 'str'
> 
> Wouldn't an enum type be better than an open-ended string?
> 

Bit names are not known here, they are obtained from virtio device
implementations.

>> +}
>> +}
>> +
>> +##
>> +# @VirtioInfoDevice:
>> +#
>> +# Information about specific virtio device
>> +#
>> +# @qom_path: QOM path of the device
> 
> Please make this 'qom-path' - new interfaces should prefer '-' over '_'.

Ok.

>> +#
>> +# @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'
> 
> I'm wondering if this is the best representation (where the caller has
> to parse the integer and then lookup in feature-names what each bit of
> the integer represents).  But I'm not sure I have anything better off
> the top of my head.
> 

Consider it as way to tell caller about names of supported features.

>> +}
>> +}
>> +
>> +##
>> +# @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'],
> 
> Why is feature-names listed at two different nestings of the return value?
> 

These are different feature names. First names are common and predefined
for all devices. Second names are device-specific.

>> +'status-names': ['VirtioInfoBit'],
>> +'devices': ['VirtioInfoDevice']
>> +}
>> +}
>> +
>> +
>> +##
>> +# @query-virtio:
>> +#
>> +# Returns generic and per-device virtio information
>> +#
>> +# Since: 2.11.0
>> +#
>> +##
>> +{
>> +'command': 'query-virtio',
>> +'returns': 'VirtioInfo'
>> +}
>>
> 

-- 
Best regards
Jan Dakinevich



[Qemu-block] [Qemu-devel] [PATCH v4 1/2] virtio: introduce `query-virtio' QMP command

2017-10-03 Thread Jan Dakinevich
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[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static const char *virtio_blk_get_feature_name(VirtIODevice *vdev,
+   unsigned feature)
+{
+static const char *names[] = {
+[VIRTIO_BLK_F_BARRIER] = "barrier",
+[VIRTIO_BLK_F_SIZE_MAX] = "size_max",
+[VIRTIO_BLK_F_SEG_MAX] = "seg_max",
+[VIRTIO_BLK_F_RO] = "ro",
+[VIRTIO_BLK_F_BLK_SIZE] = "blk_size",
+[VIRTIO_BLK_F_SCSI] = "scsi",
+[VIRTIO_BLK_F_TOPOLOGY] = "topology",
+[VIRTIO_BLK_F_FLUSH] = "flush",
+[VIRTIO_BLK_F_MQ] = "mq",
+};
+if (feature >= ARRAY_SIZE(names)) {
+return NULL;
+}
+return names[feature];
+}
+
 static void virtio_blk_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1030,6 +1050,7 @@ static void virtio_blk_class_init(ObjectClass *klass, 
void *data)
 vdc->get_config = virtio_blk_update_config;
 vdc->set_config = virtio_blk_set_config;
 vdc->get_features = virtio_blk_get_features;
+vdc->get_feature_name = virtio_blk_get_feature_name;
 vdc->set_status = virtio_blk_set_status;
 vdc->reset = virtio_blk_reset;
 vdc->save = 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[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static const char *virtio_serial_get_feature_name(VirtIODevice *vdev,
+  unsigned feature)
+{
+static const char *names[] = {
+[VIRTIO_CONSOLE_F_SIZE] = "size",
+[VIRTIO_CONSOLE_F_MULTIPORT] = "multiport",
+[VIRTIO_CONSOLE_F_EMERG_WRITE] = "emerg_write",
+};
+if (feature >= ARRAY_SIZE(names)) {
+return NULL;
+}
+return names[feature];
+}
+
 static void virtio_serial_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1170,6 +1184,7 @@ static void virtio_serial_class_init(ObjectClass *klass, 
void *data)
 vdc->realize = virtio_serial_device_realize;
 vdc->unrealize = virtio_serial_device_unrealize;
 vdc->get_features = get_features;
+vdc->get_feature_name = virtio_serial_get_feature_name;
 vdc->get_config = get_config;
 vdc->set_config = set_config;
 vdc->set_status = 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[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static const char *virtio_gpu_get_feature_name(VirtIODevice *vdev,
+   unsigned feature)
+{
+static const char *names[] = {
+[VIRTIO_GPU_F_VIRGL] = "virgl",
+};
+if (feature >= ARRAY_SIZE(names)) {
+return NULL;
+}
+return names[feature];
+}
+
 static void virtio_gpu_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1317,6 +1329,7 @@ static void virtio_gpu_class_init(ObjectClass *klass, 
void *data)
 vdc->get_config = virtio_gpu_get_config;
 vdc->set_config = virtio_gpu_set_config;
 vdc->get_features = virtio_gpu_get_features;

Re: [Qemu-block] [Qemu-devel] [PATCH v2] virtio: introduce `info virtio' hmp command

2017-09-27 Thread Jan Dakinevich

> OK but if it's useful as an hmp command, why not as a qmp command?
>

The command is designed for debugging and produces quite sightly output. 
For respective qmp command most of `info virtio' output would excessive 
and unneccesary.


On 09/27/2017 10:43 PM, Michael S. Tsirkin wrote:

On Wed, Sep 27, 2017 at 06:09:42PM +0300, Jan Dakinevich wrote:

The command is intended for exposing device specific virtio feature bits
and their negotiation status. It is convenient and useful for debug
purpose.

Names of features are taken from a devices via get_feature_name() within
VirtioDeviceClass. If certain device doesn't implement it, the command
will print only hexadecimal value of feature mask.

Cc: Denis V. Lunev 
Signed-off-by: Jan Dakinevich 


OK but if it's useful as an hmp command, why not as a qmp command?


---
v2:
* Moved hmp_info_virtio and stuff to hmp.c to avoid build error
* Added printing of device status
* Listed common virtio features

v1: http://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07247.html
---
  hmp-commands-info.hx|  14 +
  hmp.c   | 148 
  hmp.h   |   1 +
  hw/block/virtio-blk.c   |  20 ++
  hw/char/virtio-serial-bus.c |  15 +
  hw/display/virtio-gpu.c |  12 
  hw/net/virtio-net.c |  34 ++
  hw/scsi/virtio-scsi.c   |  15 +
  hw/virtio/virtio-balloon.c  |  15 +
  hw/virtio/virtio-bus.c  |   1 +
  include/hw/virtio/virtio.h  |   2 +
  monitor.c   |   1 +
  12 files changed, 278 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
  },
  
  STEXI

+@item info virtio
+@findex virtio
+Display guest and host fetures for all virtio devices.
+ETEXI
+
+{
+.name   = "virtio",
+.args_type  = "",
+.params = "",
+.help   = "show virtio info",
+.cmd= hmp_info_virtio,
+},
+
+STEXI
  @end table
  ETEXI
  
diff --git a/hmp.c b/hmp.c

index ace729d..009d808 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"
  
  #ifdef CONFIG_SPICE

  #include 
@@ -2894,3 +2895,150 @@ void hmp_info_memory_size_summary(Monitor *mon, const 
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, VirtIODevice *vdev)
+{
+uint8_t status[] = {
+VIRTIO_CONFIG_S_ACKNOWLEDGE,
+VIRTIO_CONFIG_S_DRIVER,
+VIRTIO_CONFIG_S_DRIVER_OK,
+VIRTIO_CONFIG_S_FEATURES_OK,
+VIRTIO_CONFIG_S_NEEDS_RESET,
+VIRTIO_CONFIG_S_FAILED,
+};
+const char *names[] = {
+"acknowledge",
+"driver",
+"driver_ok",
+"features_ok",
+"needs_reset"
+"failed",
+};
+const char *comma = "";
+int idx;
+
+monitor_printf(mon, "%*sstatus:   0x%02"PRIx8" ",
+   HMP_INFO_VIRTIO_INDENT, "", vdev->status);
+
+for (idx = 0; idx < ARRAY_SIZE(status); idx++) {
+if (!(vdev->status & status[idx])) {
+continue;
+}
+monitor_printf(mon, "%s%s", comma, names[idx]);
+if (names[idx]) {
+comma = ",";
+}
+}
+monitor_printf(mon, "\n");
+}
+
+static void hmp_info_virtio_print_common_features(Monitor *mon,
+  VirtIODevice *vdev)
+{
+uint64_t features[] = {
+VIRTIO_RING_F_INDIRECT_DESC,
+VIRTIO_RING_F_EVENT_IDX,
+VIRTIO_F_NOTIFY_ON_EMPTY,
+VIRTIO_F_ANY_LAYOUT,
+VIRTIO_F_IOMMU_PLATFORM,
+VIRTIO_F_VERSION_1,
+};
+const char *names[] = {
+"indirect_desc",
+"event_idx",
+"notify_on_empty",
+"any_layout",
+"iommu_platform",
+"version_1",
+};
+int idx;
+
+monitor_printf(mon, "%*scommon features:\n", HMP_INFO_VIRTIO_INDENT, "");
+
+for (idx = 0; idx < ARRAY_SIZE(features); idx++) {
+const char *ack = vdev->guest_features & features[idx] ? "acked" : "";
+
+if (!(vdev->host_features & features[idx])) {
+continue;
+}
+monitor_printf(mon, "%*s%*s%*s\n", HMP_INFO_VIRTIO_INDENT, "",
+   HMP_INFO_VIRTIO_FIELD, names[idx],
+   HMP_IN

[Qemu-block] [Qemu-devel] [PATCH v3] virtio: introduce `info virtio' hmp command

2017-09-27 Thread Jan Dakinevich
The command is intended for exposing device specific virtio feature bits
and their negotiation status. It is convenient and useful for debug
purpose.

Names of features are taken from a devices via get_feature_name() within
VirtioDeviceClass. If certain device doesn't implement it, the command
will print only hexadecimal value of feature mask.

Cc: Denis V. Lunev 
Signed-off-by: Jan Dakinevich 
---

v3:
* Avoid signed int
* Use virtio_vdev_has_feature()/virtio_host_has_feature()

v2: http://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07527.html
v1: http://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07247.html
---
 hmp-commands-info.hx|  14 +
 hmp.c   | 149 
 hmp.h   |   1 +
 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/virtio-balloon.c  |  15 +
 hw/virtio/virtio-bus.c  |   1 +
 include/hw/virtio/virtio.h  |   2 +
 monitor.c   |   1 +
 12 files changed, 283 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
 },
 
 STEXI
+@item info virtio
+@findex virtio
+Display guest and host fetures for all virtio devices.
+ETEXI
+
+{
+.name   = "virtio",
+.args_type  = "",
+.params = "",
+.help   = "show virtio info",
+.cmd= hmp_info_virtio,
+},
+
+STEXI
 @end table
 ETEXI
 
diff --git a/hmp.c b/hmp.c
index ace729d..f231395 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"
 
 #ifdef CONFIG_SPICE
 #include 
@@ -2894,3 +2895,151 @@ void hmp_info_memory_size_summary(Monitor *mon, const 
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, VirtIODevice *vdev)
+{
+uint8_t status[] = {
+VIRTIO_CONFIG_S_ACKNOWLEDGE,
+VIRTIO_CONFIG_S_DRIVER,
+VIRTIO_CONFIG_S_DRIVER_OK,
+VIRTIO_CONFIG_S_FEATURES_OK,
+VIRTIO_CONFIG_S_NEEDS_RESET,
+VIRTIO_CONFIG_S_FAILED,
+};
+const char *names[] = {
+"acknowledge",
+"driver",
+"driver_ok",
+"features_ok",
+"needs_reset"
+"failed",
+};
+const char *comma = "";
+unsigned idx;
+
+monitor_printf(mon, "%*sstatus:   0x%02"PRIx8" ",
+   HMP_INFO_VIRTIO_INDENT, "", vdev->status);
+
+for (idx = 0; idx < ARRAY_SIZE(status); idx++) {
+if (!(vdev->status & status[idx])) {
+continue;
+}
+monitor_printf(mon, "%s%s", comma, names[idx]);
+if (names[idx]) {
+comma = ",";
+}
+}
+monitor_printf(mon, "\n");
+}
+
+static void hmp_info_virtio_print_common_features(Monitor *mon,
+  VirtIODevice *vdev)
+{
+uint64_t features[] = {
+VIRTIO_RING_F_INDIRECT_DESC,
+VIRTIO_RING_F_EVENT_IDX,
+VIRTIO_F_NOTIFY_ON_EMPTY,
+VIRTIO_F_ANY_LAYOUT,
+VIRTIO_F_IOMMU_PLATFORM,
+VIRTIO_F_VERSION_1,
+};
+const char *names[] = {
+"indirect_desc",
+"event_idx",
+"notify_on_empty",
+"any_layout",
+"iommu_platform",
+"version_1",
+};
+unsigned idx;
+
+monitor_printf(mon, "%*scommon features:\n", HMP_INFO_VIRTIO_INDENT, "");
+
+for (idx = 0; idx < ARRAY_SIZE(features); idx++) {
+const char *ack = virtio_vdev_has_feature(vdev, features[idx])
+? "acked" : "";
+
+if (!virtio_host_has_feature(vdev, features[idx])) {
+continue;
+}
+monitor_printf(mon, "%*s%*s%*s\n", HMP_INFO_VIRTIO_INDENT, "",
+   HMP_INFO_VIRTIO_FIELD, names[idx],
+   HMP_INFO_VIRTIO_FIELD, ack);
+}
+}
+
+static void hmp_info_virtio_print_specific_features(Monitor *mon,
+VirtIODevice *vdev)
+{
+VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
+unsigned idx;
+
+if (!vdc->get_feature_name) {
+return;
+}
+
+monitor_printf(mon, "%*sspecific features:\n", HMP_INFO_VIRTIO_INDENT, &q

Re: [Qemu-block] [Qemu-devel] [PATCH v2] virtio: introduce `info virtio' hmp command

2017-09-27 Thread Jan Dakinevich


On 09/27/2017 06:53 PM, Dr. David Alan Gilbert wrote:
> * Jan Dakinevich (jan.dakinev...@virtuozzo.com) wrote:
>> The command is intended for exposing device specific virtio feature bits
>> and their negotiation status. It is convenient and useful for debug
>> purpose.
>>
>> Names of features are taken from a devices via get_feature_name() within
>> VirtioDeviceClass. If certain device doesn't implement it, the command
>> will print only hexadecimal value of feature mask.
>>
>> Cc: Denis V. Lunev 
>> Signed-off-by: Jan Dakinevich 
>> ---
>> v2:
>> * Moved hmp_info_virtio and stuff to hmp.c to avoid build error
>> * Added printing of device status
>> * Listed common virtio features
>>
>> v1: http://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07247.html
>> ---
>>  hmp-commands-info.hx|  14 +
>>  hmp.c   | 148 
>> 
>>  hmp.h   |   1 +
>>  hw/block/virtio-blk.c   |  20 ++
>>  hw/char/virtio-serial-bus.c |  15 +
>>  hw/display/virtio-gpu.c |  12 
>>  hw/net/virtio-net.c |  34 ++
>>  hw/scsi/virtio-scsi.c   |  15 +
>>  hw/virtio/virtio-balloon.c  |  15 +
>>  hw/virtio/virtio-bus.c  |   1 +
>>  include/hw/virtio/virtio.h  |   2 +
>>  monitor.c   |   1 +
>>  12 files changed, 278 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
>>  },
>>  
>>  STEXI
>> +@item info virtio
>> +@findex virtio
>> +Display guest and host fetures for all virtio devices.
>> +ETEXI
>> +
>> +{
>> +.name   = "virtio",
>> +.args_type  = "",
>> +.params = "",
>> +.help   = "show virtio info",
>> +.cmd= hmp_info_virtio,
>> +},
>> +
>> +STEXI
>>  @end table
>>  ETEXI
>>  
>> diff --git a/hmp.c b/hmp.c
>> index ace729d..009d808 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"
>>  
>>  #ifdef CONFIG_SPICE
>>  #include 
>> @@ -2894,3 +2895,150 @@ void hmp_info_memory_size_summary(Monitor *mon, 
>> const 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, VirtIODevice *vdev)
>> +{
>> +uint8_t status[] = {
>> +VIRTIO_CONFIG_S_ACKNOWLEDGE,
>> +VIRTIO_CONFIG_S_DRIVER,
>> +VIRTIO_CONFIG_S_DRIVER_OK,
>> +VIRTIO_CONFIG_S_FEATURES_OK,
>> +VIRTIO_CONFIG_S_NEEDS_RESET,
>> +VIRTIO_CONFIG_S_FAILED,
>> +};
>> +const char *names[] = {
>> +"acknowledge",
>> +"driver",
>> +"driver_ok",
>> +"features_ok",
>> +"needs_reset"
>> +"failed",
>> +};
>> +const char *comma = "";
>> +int idx;
>> +
>> +monitor_printf(mon, "%*sstatus:   0x%02"PRIx8" ",
>> +   HMP_INFO_VIRTIO_INDENT, "", vdev->status);
>> +
>> +for (idx = 0; idx < ARRAY_SIZE(status); idx++) {
>> +if (!(vdev->status & status[idx])) {
>> +continue;
>> +}
>> +monitor_printf(mon, "%s%s", comma, names[idx]);
>> +if (names[idx]) {
>> +comma = ",";
>> +}
>> +}
>> +monitor_printf(mon, "\n");
>> +}
>> +
>> +static void hmp_info_virtio_print_common_features(Monitor *mon,
>> +  VirtIODevice *vdev)
>> +{
>> +uint64_t features[] = {
>> +VIRTIO_RING_F_INDIRECT_DESC,
>> +VIRTIO_RING_F_EVENT_IDX,
>> +VIRTIO_F_NOTIFY_ON_EMPTY,
>> +VIRTIO_F_ANY_LAYOUT,
>> +VIRTIO_F_IOMMU_PLATFORM,
>> +VIRTIO_F_VERSION_1,
>> +};
>> +const char 

[Qemu-block] [Qemu-devel] [PATCH v2] virtio: introduce `info virtio' hmp command

2017-09-27 Thread Jan Dakinevich
The command is intended for exposing device specific virtio feature bits
and their negotiation status. It is convenient and useful for debug
purpose.

Names of features are taken from a devices via get_feature_name() within
VirtioDeviceClass. If certain device doesn't implement it, the command
will print only hexadecimal value of feature mask.

Cc: Denis V. Lunev 
Signed-off-by: Jan Dakinevich 
---
v2:
* Moved hmp_info_virtio and stuff to hmp.c to avoid build error
* Added printing of device status
* Listed common virtio features

v1: http://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07247.html
---
 hmp-commands-info.hx|  14 +
 hmp.c   | 148 
 hmp.h   |   1 +
 hw/block/virtio-blk.c   |  20 ++
 hw/char/virtio-serial-bus.c |  15 +
 hw/display/virtio-gpu.c |  12 
 hw/net/virtio-net.c |  34 ++
 hw/scsi/virtio-scsi.c   |  15 +
 hw/virtio/virtio-balloon.c  |  15 +
 hw/virtio/virtio-bus.c  |   1 +
 include/hw/virtio/virtio.h  |   2 +
 monitor.c   |   1 +
 12 files changed, 278 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
 },
 
 STEXI
+@item info virtio
+@findex virtio
+Display guest and host fetures for all virtio devices.
+ETEXI
+
+{
+.name   = "virtio",
+.args_type  = "",
+.params = "",
+.help   = "show virtio info",
+.cmd= hmp_info_virtio,
+},
+
+STEXI
 @end table
 ETEXI
 
diff --git a/hmp.c b/hmp.c
index ace729d..009d808 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"
 
 #ifdef CONFIG_SPICE
 #include 
@@ -2894,3 +2895,150 @@ void hmp_info_memory_size_summary(Monitor *mon, const 
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, VirtIODevice *vdev)
+{
+uint8_t status[] = {
+VIRTIO_CONFIG_S_ACKNOWLEDGE,
+VIRTIO_CONFIG_S_DRIVER,
+VIRTIO_CONFIG_S_DRIVER_OK,
+VIRTIO_CONFIG_S_FEATURES_OK,
+VIRTIO_CONFIG_S_NEEDS_RESET,
+VIRTIO_CONFIG_S_FAILED,
+};
+const char *names[] = {
+"acknowledge",
+"driver",
+"driver_ok",
+"features_ok",
+"needs_reset"
+"failed",
+};
+const char *comma = "";
+int idx;
+
+monitor_printf(mon, "%*sstatus:   0x%02"PRIx8" ",
+   HMP_INFO_VIRTIO_INDENT, "", vdev->status);
+
+for (idx = 0; idx < ARRAY_SIZE(status); idx++) {
+if (!(vdev->status & status[idx])) {
+continue;
+}
+monitor_printf(mon, "%s%s", comma, names[idx]);
+if (names[idx]) {
+comma = ",";
+}
+}
+monitor_printf(mon, "\n");
+}
+
+static void hmp_info_virtio_print_common_features(Monitor *mon,
+  VirtIODevice *vdev)
+{
+uint64_t features[] = {
+VIRTIO_RING_F_INDIRECT_DESC,
+VIRTIO_RING_F_EVENT_IDX,
+VIRTIO_F_NOTIFY_ON_EMPTY,
+VIRTIO_F_ANY_LAYOUT,
+VIRTIO_F_IOMMU_PLATFORM,
+VIRTIO_F_VERSION_1,
+};
+const char *names[] = {
+"indirect_desc",
+"event_idx",
+"notify_on_empty",
+"any_layout",
+"iommu_platform",
+"version_1",
+};
+int idx;
+
+monitor_printf(mon, "%*scommon features:\n", HMP_INFO_VIRTIO_INDENT, "");
+
+for (idx = 0; idx < ARRAY_SIZE(features); idx++) {
+const char *ack = vdev->guest_features & features[idx] ? "acked" : "";
+
+if (!(vdev->host_features & features[idx])) {
+continue;
+}
+monitor_printf(mon, "%*s%*s%*s\n", HMP_INFO_VIRTIO_INDENT, "",
+   HMP_INFO_VIRTIO_FIELD, names[idx],
+   HMP_INFO_VIRTIO_FIELD, ack);
+}
+}
+
+static void hmp_info_virtio_print_specific_features(Monitor *mon,
+VirtIODevice *vdev)
+{
+VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
+int idx;
+
+if (!vdc->get_feature_name) {
+return;
+}
+
+monitor_printf(mon, "%*sspecific features:\n", HMP_INFO_VIRTIO_INDENT, "");
+
+for (idx = 0; idx < 64; idx++) {
+co

[Qemu-block] [PATCH] virtio: introduce `info virtio' hmp command

2017-09-26 Thread Jan Dakinevich
The command is intended for exposing device specific virtio feature bits
and their negotiation status. It is convenient and useful for debug
purpose.

Names of features are taken from a devices via get_feature_name() within
VirtioDeviceClass. If certain device doesn't implement it, the command
will print only hexadecimal value of feature mask.

Cc: Denis V. Lunev 
Signed-off-by: Jan Dakinevich 
---
The patch suggests an another approach for this:

"virtio: show guest features in 'info qtree'"
http://lists.nongnu.org/archive/html/qemu-devel/2016-05/msg01609.html
---
 hmp-commands-info.hx   | 14 ++
 hw/block/virtio-blk.c  | 20 ++
 hw/char/virtio-serial-bus.c| 15 +++
 hw/display/virtio-gpu.c| 12 +
 hw/net/virtio-net.c| 34 
 hw/scsi/virtio-scsi.c  | 15 +++
 hw/virtio/virtio-balloon.c | 15 +++
 hw/virtio/virtio-bus.c | 59 ++
 include/hw/virtio/virtio-bus.h |  2 ++
 include/hw/virtio/virtio.h |  2 ++
 monitor.c  |  1 +
 11 files changed, 189 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
 },
 
 STEXI
+@item info virtio
+@findex virtio
+Display guest and host fetures for all virtio devices.
+ETEXI
+
+{
+.name   = "virtio",
+.args_type  = "",
+.params = "",
+.help   = "show virtio info",
+.cmd= hmp_info_virtio,
+},
+
+STEXI
 @end table
 ETEXI
 
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 05d1440..5856640 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1017,6 +1017,25 @@ static Property virtio_blk_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static const char *virtio_blk_get_feature_name(VirtIODevice *vdev, int feature)
+{
+static const char *names[] = {
+[VIRTIO_BLK_F_BARRIER] = "barrier",
+[VIRTIO_BLK_F_SIZE_MAX] = "size_max",
+[VIRTIO_BLK_F_SEG_MAX] = "seg_max",
+[VIRTIO_BLK_F_RO] = "ro",
+[VIRTIO_BLK_F_BLK_SIZE] = "blk_size",
+[VIRTIO_BLK_F_SCSI] = "scsi",
+[VIRTIO_BLK_F_TOPOLOGY] = "topology",
+[VIRTIO_BLK_F_FLUSH] = "flush",
+[VIRTIO_BLK_F_MQ] = "mq",
+};
+if (feature >= ARRAY_SIZE(names)) {
+return NULL;
+}
+return names[feature];
+}
+
 static void virtio_blk_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1030,6 +1049,7 @@ static void virtio_blk_class_init(ObjectClass *klass, 
void *data)
 vdc->get_config = virtio_blk_update_config;
 vdc->set_config = virtio_blk_set_config;
 vdc->get_features = virtio_blk_get_features;
+vdc->get_feature_name = virtio_blk_get_feature_name;
 vdc->set_status = virtio_blk_set_status;
 vdc->reset = virtio_blk_reset;
 vdc->save = virtio_blk_save_device;
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 9470bd7..a6ccb6a 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -1156,6 +1156,20 @@ static Property virtio_serial_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static const char *virtio_serial_get_feature_name(VirtIODevice *vdev,
+  int feature)
+{
+static const char *names[] = {
+[VIRTIO_CONSOLE_F_SIZE] = "size",
+[VIRTIO_CONSOLE_F_MULTIPORT] = "multiport",
+[VIRTIO_CONSOLE_F_EMERG_WRITE] = "emerg_write",
+};
+if (feature >= ARRAY_SIZE(names)) {
+return NULL;
+}
+return names[feature];
+}
+
 static void virtio_serial_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1170,6 +1184,7 @@ static void virtio_serial_class_init(ObjectClass *klass, 
void *data)
 vdc->realize = virtio_serial_device_realize;
 vdc->unrealize = virtio_serial_device_unrealize;
 vdc->get_features = get_features;
+vdc->get_feature_name = virtio_serial_get_feature_name;
 vdc->get_config = get_config;
 vdc->set_config = set_config;
 vdc->set_status = set_status;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 3a8f1e1..860d2b3 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1307,6 +1307,17 @@ static Property virtio_gpu_properties[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static const char *virtio_gpu_get_feature_name(VirtIODevice *vdev, int feature)
+{
+static const char *names[] = {
+[VIRTIO_GPU_F_VIRGL] = "virgl",
+};
+if (feature >= ARRAY_