Message ID | 1626086137-16292-2-git-send-email-jonah.palmer@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | hmp, qmp: Add some commands to introspect virtio devices | expand |
QAPI schema review only. Jonah Palmer <jonah.palmer@oracle.com> writes: > From: Laurent Vivier <lvivier@redhat.com> > > This new command lists all the instances of VirtIODevice with > their path and virtio type. > > Signed-off-by: Laurent Vivier <lvivier@redhat.com> > Reviewed-by: Eric Blake <eblake@redhat.com> > Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com> [...] > diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json > index 4912b97..0c89789 100644 > --- a/qapi/qapi-schema.json > +++ b/qapi/qapi-schema.json > @@ -91,5 +91,6 @@ > { 'include': 'misc.json' } > { 'include': 'misc-target.json' } > { 'include': 'audio.json' } > +{ 'include': 'virtio.json' } > { 'include': 'acpi.json' } > { 'include': 'pci.json' } > diff --git a/qapi/virtio.json b/qapi/virtio.json > new file mode 100644 > index 0000000..804adbe > --- /dev/null > +++ b/qapi/virtio.json > @@ -0,0 +1,72 @@ Please insert at the beginning # -*- Mode: Python -*- # vim: filetype=python # > +## > +# = Virtio devices > +## > + > +## > +# @VirtioType: > +# > +# An enumeration of Virtio device types. > +# > +# Since: 6.1 6.2 now, here and below. > +## > +{ 'enum': 'VirtioType', > + 'data': [ 'unknown', 'virtio-net', 'virtio-blk', 'virtio-console', > + 'virtio-rng', 'virtio-balloon', 'virtio-iomem', 'virtio-rpmsg', > + 'virtio-scsi', 'virtio-9p', 'virtio-mac80211-wlan', > + 'virtio-serial', 'virtio-caif', 'virtio-memory-balloon', > + 'unknown-14', 'unknown-15', 'virtio-gpu', 'virtio-clock', > + 'virtio-input', 'vhost-vsock', 'virtio-crypto', 'virtio-signal-dist', > + 'virtio-pstore', 'virtio-iommu', 'virtio-mem', 'unknown-25', > + 'vhost-user-fs', 'virtio-pmem', 'unknown-28', 'virtio-mac80211-hwsim' ] Please limit line length to approximately 70 characters. > +} > + > +## > +# @VirtioInfo: > +# > +# Information about a given VirtIODevice > +# > +# @path: VirtIO device canonical path. Peeking ahead at the example, I conclude this is a QOM path. Please spell that out, e.g. "@path: the device's canonical QOM path". > +# > +# @type: VirtIO device type. > +# > +# Since: 6.1 > +# > +## > +{ 'struct': 'VirtioInfo', > + 'data': { > + 'path': 'str', > + 'type': 'VirtioType' > + } > +} > + > +## > +# @x-debug-query-virtio: > +# > +# Return the list of all VirtIO devices > +# > +# Returns: list of @VirtioInfo > +# > +# Since: 6.1 > +# > +# Example: > +# > +# -> { "execute": "x-debug-query-virtio" } > +# <- { "return": [ > +# { > +# "path": "/machine/peripheral-anon/device[3]/virtio-backend", > +# "type": "virtio-net" > +# }, > +# { > +# "path": "/machine/peripheral-anon/device[1]/virtio-backend", > +# "type": "virtio-serial" > +# }, > +# { > +# "path": "/machine/peripheral-anon/device[0]/virtio-backend", > +# "type": "virtio-blk" > +# } > +# ] > +# } > +# > +## > + > +{ 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] } [...]
On 8/7/21 8:35 AM, Markus Armbruster wrote: > QAPI schema review only. > > Jonah Palmer <jonah.palmer@oracle.com> writes: > >> From: Laurent Vivier <lvivier@redhat.com> >> >> This new command lists all the instances of VirtIODevice with >> their path and virtio type. >> >> Signed-off-by: Laurent Vivier <lvivier@redhat.com> >> Reviewed-by: Eric Blake <eblake@redhat.com> >> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com> > [...] > >> diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json >> index 4912b97..0c89789 100644 >> --- a/qapi/qapi-schema.json >> +++ b/qapi/qapi-schema.json >> @@ -91,5 +91,6 @@ >> { 'include': 'misc.json' } >> { 'include': 'misc-target.json' } >> { 'include': 'audio.json' } >> +{ 'include': 'virtio.json' } >> { 'include': 'acpi.json' } >> { 'include': 'pci.json' } >> diff --git a/qapi/virtio.json b/qapi/virtio.json >> new file mode 100644 >> index 0000000..804adbe >> --- /dev/null >> +++ b/qapi/virtio.json >> @@ -0,0 +1,72 @@ > Please insert at the beginning > > # -*- Mode: Python -*- > # vim: filetype=python > # Will do. >> +## >> +# = Virtio devices >> +## >> + >> +## >> +# @VirtioType: >> +# >> +# An enumeration of Virtio device types. >> +# >> +# Since: 6.1 > 6.2 now, here and below. Okay, will update for entire series. > >> +## >> +{ 'enum': 'VirtioType', >> + 'data': [ 'unknown', 'virtio-net', 'virtio-blk', 'virtio-console', >> + 'virtio-rng', 'virtio-balloon', 'virtio-iomem', 'virtio-rpmsg', >> + 'virtio-scsi', 'virtio-9p', 'virtio-mac80211-wlan', >> + 'virtio-serial', 'virtio-caif', 'virtio-memory-balloon', >> + 'unknown-14', 'unknown-15', 'virtio-gpu', 'virtio-clock', >> + 'virtio-input', 'vhost-vsock', 'virtio-crypto', 'virtio-signal-dist', >> + 'virtio-pstore', 'virtio-iommu', 'virtio-mem', 'unknown-25', >> + 'vhost-user-fs', 'virtio-pmem', 'unknown-28', 'virtio-mac80211-hwsim' ] > Please limit line length to approximately 70 characters. Fixed, sorry about that. Also, should I continue this up to 'virtio-bluetooth'? E.g: ... 'virtio-mac80211-hwsim', 'unknown-30', 'unknown-31', 'unknown-32', 'unknown-33', 'unknown-34', 'unknown-35', 'unknown-36', 'unknown-37', 'unknown-38', 'unknown-39', 'virtio-bluetooth' ] > >> +} >> + >> +## >> +# @VirtioInfo: >> +# >> +# Information about a given VirtIODevice >> +# >> +# @path: VirtIO device canonical path. > Peeking ahead at the example, I conclude this is a QOM path. Please > spell that out, e.g. "@path: the device's canonical QOM path". Got it - will do for rest of occurrences in the series. > >> +# >> +# @type: VirtIO device type. >> +# >> +# Since: 6.1 >> +# >> +## >> +{ 'struct': 'VirtioInfo', >> + 'data': { >> + 'path': 'str', >> + 'type': 'VirtioType' >> + } >> +} >> + >> +## >> +# @x-debug-query-virtio: >> +# >> +# Return the list of all VirtIO devices >> +# >> +# Returns: list of @VirtioInfo >> +# >> +# Since: 6.1 >> +# >> +# Example: >> +# >> +# -> { "execute": "x-debug-query-virtio" } >> +# <- { "return": [ >> +# { >> +# "path": "/machine/peripheral-anon/device[3]/virtio-backend", >> +# "type": "virtio-net" >> +# }, >> +# { >> +# "path": "/machine/peripheral-anon/device[1]/virtio-backend", >> +# "type": "virtio-serial" >> +# }, >> +# { >> +# "path": "/machine/peripheral-anon/device[0]/virtio-backend", >> +# "type": "virtio-blk" >> +# } >> +# ] >> +# } >> +# >> +## >> + >> +{ 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] } > [...] >
Back from my summer break, please excuse the delay. Jonah Palmer <jonah.palmer@oracle.com> writes: > On 8/7/21 8:35 AM, Markus Armbruster wrote: >> QAPI schema review only. >> >> Jonah Palmer <jonah.palmer@oracle.com> writes: >> >>> From: Laurent Vivier <lvivier@redhat.com> >>> >>> This new command lists all the instances of VirtIODevice with >>> their path and virtio type. >>> >>> Signed-off-by: Laurent Vivier <lvivier@redhat.com> >>> Reviewed-by: Eric Blake <eblake@redhat.com> >>> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com> >> [...] >> >>> diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json >>> index 4912b97..0c89789 100644 >>> --- a/qapi/qapi-schema.json >>> +++ b/qapi/qapi-schema.json >>> @@ -91,5 +91,6 @@ >>> { 'include': 'misc.json' } >>> { 'include': 'misc-target.json' } >>> { 'include': 'audio.json' } >>> +{ 'include': 'virtio.json' } >>> { 'include': 'acpi.json' } >>> { 'include': 'pci.json' } >>> diff --git a/qapi/virtio.json b/qapi/virtio.json >>> new file mode 100644 >>> index 0000000..804adbe >>> --- /dev/null >>> +++ b/qapi/virtio.json >>> @@ -0,0 +1,72 @@ >> Please insert at the beginning >> >> # -*- Mode: Python -*- >> # vim: filetype=python >> # > > Will do. > >>> +## >>> +# = Virtio devices >>> +## >>> + >>> +## >>> +# @VirtioType: >>> +# >>> +# An enumeration of Virtio device types. >>> +# >>> +# Since: 6.1 >> 6.2 now, here and below. > > Okay, will update for entire series. > >> >>> +## >>> +{ 'enum': 'VirtioType', >>> + 'data': [ 'unknown', 'virtio-net', 'virtio-blk', 'virtio-console', >>> + 'virtio-rng', 'virtio-balloon', 'virtio-iomem', 'virtio-rpmsg', >>> + 'virtio-scsi', 'virtio-9p', 'virtio-mac80211-wlan', >>> + 'virtio-serial', 'virtio-caif', 'virtio-memory-balloon', >>> + 'unknown-14', 'unknown-15', 'virtio-gpu', 'virtio-clock', >>> + 'virtio-input', 'vhost-vsock', 'virtio-crypto', 'virtio-signal-dist', >>> + 'virtio-pstore', 'virtio-iommu', 'virtio-mem', 'unknown-25', >>> + 'vhost-user-fs', 'virtio-pmem', 'unknown-28', 'virtio-mac80211-hwsim' ] >> Please limit line length to approximately 70 characters. > > Fixed, sorry about that. Also, should I continue this up to 'virtio-bluetooth'? E.g: > > ... > 'virtio-mac80211-hwsim', 'unknown-30', 'unknown-31', > 'unknown-32', 'unknown-33', 'unknown-34', 'unknown-35', > 'unknown-36', 'unknown-37', 'unknown-38', 'unknown-39', > 'virtio-bluetooth' ] Hmm... how is this enum used? In this patch: VirtioInfoList *qmp_x_debug_query_virtio(Error **errp) { VirtioInfoList *list = NULL; VirtioInfoList *node; VirtIODevice *vdev; QTAILQ_FOREACH(vdev, &virtio_list, next) { DeviceState *dev = DEVICE(vdev); node = g_new0(VirtioInfoList, 1); node->value = g_new(VirtioInfo, 1); node->value->path = g_strdup(dev->canonical_path); ---> node->value->type = qapi_enum_parse(&VirtioType_lookup, vdev->name, ---> VIRTIO_TYPE_UNKNOWN, NULL); QAPI_LIST_PREPEND(list, node->value); } return list; } This maps VirtioDevice member @name (a string) to an enum value. As far as I can tell, this member is set in virtio_init() only, to its argument. All callers pass string literals. They also pass a numeric device_id, and the two seem to match, e.g. "virtio-blk" and VIRTIO_ID_BLOCK. Thus, the pairs (numeric device ID, string device ID) already exist in the code, but not in a way that lets you map between them. To get that, you *duplicate* the pairs in QAPI. Having two copies means we get to keep them consistent. Can we avoid that? The enum has a special member 'unknown' that gets used when @name does not parse as enum member, i.e. we failed at keeping the copies consistent. I'm afraid this sweeps a programming error under the rug. The enum has a bunch of dummy members like 'unknown-14' to make QAPI generate numeric enum values match the device IDs. Error prone. Can't see offhand why we need them to match. What about the following. Define a map from numeric device ID to string, like so const char *virtio_device_name[] = { [VIRTIO_ID_NET] = "virtio-net", [VIRTIO_ID_BLOCK] = "virtio-blk", ... } This lets you * map device ID to string by subscripting virtio_device_name[]. Guarding with assert(device_id < G_N_ELEMENTS(virtio_device_name)) may be advisable. * map string to device ID by searching virtio_device_name[]. May want a function for that, Now you can have virtio_init() map parameter @device_id to string, and drop parameter @name. Then you have two options: 1. With QAPI enum VirtioType Define it without the special and the dummy members. To map from string to QAPI enum, use qapi_enum_parse(). To map from QAPI enum to string, use VirtioType_str(). To map from QAPI enum to device ID, map through string. 2. Without QAPI enum VirtioType Simply use uint16_t device_id, just like struct VirtioDevice. The choice between 1. and 2. depends on whether you actually need additional functionality provided by QAPI, such as types being visible in query-qmp-schema. [...]
No problem! Comments below: On 8/23/21 9:27 AM, Markus Armbruster wrote: > Back from my summer break, please excuse the delay. > > Jonah Palmer <jonah.palmer@oracle.com> writes: > >> On 8/7/21 8:35 AM, Markus Armbruster wrote: >>> QAPI schema review only. >>> >>> Jonah Palmer <jonah.palmer@oracle.com> writes: >>> >>>> From: Laurent Vivier <lvivier@redhat.com> >>>> >>>> This new command lists all the instances of VirtIODevice with >>>> their path and virtio type. >>>> >>>> Signed-off-by: Laurent Vivier <lvivier@redhat.com> >>>> Reviewed-by: Eric Blake <eblake@redhat.com> >>>> Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com> >>> [...] >>> >>>> diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json >>>> index 4912b97..0c89789 100644 >>>> --- a/qapi/qapi-schema.json >>>> +++ b/qapi/qapi-schema.json >>>> @@ -91,5 +91,6 @@ >>>> { 'include': 'misc.json' } >>>> { 'include': 'misc-target.json' } >>>> { 'include': 'audio.json' } >>>> +{ 'include': 'virtio.json' } >>>> { 'include': 'acpi.json' } >>>> { 'include': 'pci.json' } >>>> diff --git a/qapi/virtio.json b/qapi/virtio.json >>>> new file mode 100644 >>>> index 0000000..804adbe >>>> --- /dev/null >>>> +++ b/qapi/virtio.json >>>> @@ -0,0 +1,72 @@ >>> Please insert at the beginning >>> >>> # -*- Mode: Python -*- >>> # vim: filetype=python >>> # >> Will do. >> >>>> +## >>>> +# = Virtio devices >>>> +## >>>> + >>>> +## >>>> +# @VirtioType: >>>> +# >>>> +# An enumeration of Virtio device types. >>>> +# >>>> +# Since: 6.1 >>> 6.2 now, here and below. >> Okay, will update for entire series. >> >>>> +## >>>> +{ 'enum': 'VirtioType', >>>> + 'data': [ 'unknown', 'virtio-net', 'virtio-blk', 'virtio-console', >>>> + 'virtio-rng', 'virtio-balloon', 'virtio-iomem', 'virtio-rpmsg', >>>> + 'virtio-scsi', 'virtio-9p', 'virtio-mac80211-wlan', >>>> + 'virtio-serial', 'virtio-caif', 'virtio-memory-balloon', >>>> + 'unknown-14', 'unknown-15', 'virtio-gpu', 'virtio-clock', >>>> + 'virtio-input', 'vhost-vsock', 'virtio-crypto', 'virtio-signal-dist', >>>> + 'virtio-pstore', 'virtio-iommu', 'virtio-mem', 'unknown-25', >>>> + 'vhost-user-fs', 'virtio-pmem', 'unknown-28', 'virtio-mac80211-hwsim' ] >>> Please limit line length to approximately 70 characters. >> Fixed, sorry about that. Also, should I continue this up to 'virtio-bluetooth'? E.g: >> >> ... >> 'virtio-mac80211-hwsim', 'unknown-30', 'unknown-31', >> 'unknown-32', 'unknown-33', 'unknown-34', 'unknown-35', >> 'unknown-36', 'unknown-37', 'unknown-38', 'unknown-39', >> 'virtio-bluetooth' ] > Hmm... how is this enum used? In this patch: > > VirtioInfoList *qmp_x_debug_query_virtio(Error **errp) > { > VirtioInfoList *list = NULL; > VirtioInfoList *node; > VirtIODevice *vdev; > > QTAILQ_FOREACH(vdev, &virtio_list, next) { > DeviceState *dev = DEVICE(vdev); > node = g_new0(VirtioInfoList, 1); > node->value = g_new(VirtioInfo, 1); > node->value->path = g_strdup(dev->canonical_path); > ---> node->value->type = qapi_enum_parse(&VirtioType_lookup, vdev->name, > ---> VIRTIO_TYPE_UNKNOWN, NULL); > QAPI_LIST_PREPEND(list, node->value); > } > > return list; > } > > This maps VirtioDevice member @name (a string) to an enum value. > > As far as I can tell, this member is set in virtio_init() only, to its > argument. All callers pass string literals. They also pass a numeric > device_id, and the two seem to match, e.g. "virtio-blk" and > VIRTIO_ID_BLOCK. > > Thus, the pairs (numeric device ID, string device ID) already exist in > the code, but not in a way that lets you map between them. To get that, > you *duplicate* the pairs in QAPI. > > Having two copies means we get to keep them consistent. Can we avoid > that? > > The enum has a special member 'unknown' that gets used when @name does > not parse as enum member, i.e. we failed at keeping the copies > consistent. I'm afraid this sweeps a programming error under the rug. > > The enum has a bunch of dummy members like 'unknown-14' to make QAPI > generate numeric enum values match the device IDs. Error prone. Can't > see offhand why we need them to match. Sure, I don't mind doing this instead. Just as an FYI, from the previous RFC series (RFC v5 1/6), David recommended here that I create a list of all the types and in the same order as include/standard-headers/linux/virtio_ids.h. The benefit from this was that we never have to convert between the QAPI number and the header number. Let me know if this is still something you'd like me to do! > > What about the following. Define a map from numeric device ID to > string, like so > > const char *virtio_device_name[] = { > [VIRTIO_ID_NET] = "virtio-net", > [VIRTIO_ID_BLOCK] = "virtio-blk", > ... > } Sorry if this is obvious, but where should I define this mapping? virtio.c or virtio.h? Jonah > This lets you > > * map device ID to string by subscripting virtio_device_name[]. > Guarding with assert(device_id < G_N_ELEMENTS(virtio_device_name)) may > be advisable. > > * map string to device ID by searching virtio_device_name[]. May want a > function for that, > > Now you can have virtio_init() map parameter @device_id to string, and > drop parameter @name. > > Then you have two options: > > 1. With QAPI enum VirtioType > > Define it without the special and the dummy members. > > To map from string to QAPI enum, use qapi_enum_parse(). > > To map from QAPI enum to string, use VirtioType_str(). > > To map from QAPI enum to device ID, map through string. > > 2. Without QAPI enum VirtioType > > Simply use uint16_t device_id, just like struct VirtioDevice. > > The choice between 1. and 2. depends on whether you actually need > additional functionality provided by QAPI, such as types being visible > in query-qmp-schema. > > [...] >
Jonah Palmer <jonah.palmer@oracle.com> writes: > No problem! Comments below: > > On 8/23/21 9:27 AM, Markus Armbruster wrote: [...] >> Hmm... how is this enum used? In this patch: >> >> VirtioInfoList *qmp_x_debug_query_virtio(Error **errp) >> { >> VirtioInfoList *list = NULL; >> VirtioInfoList *node; >> VirtIODevice *vdev; >> >> QTAILQ_FOREACH(vdev, &virtio_list, next) { >> DeviceState *dev = DEVICE(vdev); >> node = g_new0(VirtioInfoList, 1); >> node->value = g_new(VirtioInfo, 1); >> node->value->path = g_strdup(dev->canonical_path); >> ---> node->value->type = qapi_enum_parse(&VirtioType_lookup, vdev->name, >> ---> VIRTIO_TYPE_UNKNOWN, NULL); >> QAPI_LIST_PREPEND(list, node->value); >> } >> >> return list; >> } >> >> This maps VirtioDevice member @name (a string) to an enum value. >> >> As far as I can tell, this member is set in virtio_init() only, to its >> argument. All callers pass string literals. They also pass a numeric >> device_id, and the two seem to match, e.g. "virtio-blk" and >> VIRTIO_ID_BLOCK. >> >> Thus, the pairs (numeric device ID, string device ID) already exist in >> the code, but not in a way that lets you map between them. To get that, >> you *duplicate* the pairs in QAPI. >> >> Having two copies means we get to keep them consistent. Can we avoid >> that? >> >> The enum has a special member 'unknown' that gets used when @name does >> not parse as enum member, i.e. we failed at keeping the copies >> consistent. I'm afraid this sweeps a programming error under the rug. >> >> The enum has a bunch of dummy members like 'unknown-14' to make QAPI >> generate numeric enum values match the device IDs. Error prone. Can't >> see offhand why we need them to match. > > Sure, I don't mind doing this instead. Just as an FYI, from the previous > RFC series (RFC v5 1/6), David recommended here that I create a list of > all the types and in the same order as include/standard-headers/linux/virtio_ids.h. > > The benefit from this was that we never have to convert between the QAPI number > and the header number. Yes, but it comes with the disadvantages I listed above. > Let me know if this is still something you'd like me to do! I think it's simpler overall, especially if you can pick option "2. Without QAPI enum VirtioType" below. I could be wrong. Suggest to try it out to see what you like better. >> >> What about the following. Define a map from numeric device ID to >> string, like so >> >> const char *virtio_device_name[] = { >> [VIRTIO_ID_NET] = "virtio-net", >> [VIRTIO_ID_BLOCK] = "virtio-blk", >> ... >> } > > Sorry if this is obvious, but where should I define this mapping? > virtio.c or virtio.h? Variable definitions normally live in .c. > Jonah > >> This lets you >> >> * map device ID to string by subscripting virtio_device_name[]. >> Guarding with assert(device_id < G_N_ELEMENTS(virtio_device_name)) may >> be advisable. >> >> * map string to device ID by searching virtio_device_name[]. May want a >> function for that, >> >> Now you can have virtio_init() map parameter @device_id to string, and >> drop parameter @name. >> >> Then you have two options: >> >> 1. With QAPI enum VirtioType >> >> Define it without the special and the dummy members. >> >> To map from string to QAPI enum, use qapi_enum_parse(). >> >> To map from QAPI enum to string, use VirtioType_str(). >> >> To map from QAPI enum to device ID, map through string. >> >> 2. Without QAPI enum VirtioType >> >> Simply use uint16_t device_id, just like struct VirtioDevice. >> >> The choice between 1. and 2. depends on whether you actually need >> additional functionality provided by QAPI, such as types being visible >> in query-qmp-schema. >> >> [...] >>
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build index fbff9bc..81dc4c9 100644 --- a/hw/virtio/meson.build +++ b/hw/virtio/meson.build @@ -6,8 +6,10 @@ softmmu_virtio_ss.add(when: 'CONFIG_VHOST', if_false: files('vhost-stub.c')) softmmu_ss.add_all(when: 'CONFIG_VIRTIO', if_true: softmmu_virtio_ss) softmmu_ss.add(when: 'CONFIG_VIRTIO', if_false: files('vhost-stub.c')) +softmmu_ss.add(when: 'CONFIG_VIRTIO', if_false: files('virtio-stub.c')) softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('vhost-stub.c')) +softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('virtio-stub.c')) virtio_ss = ss.source_set() virtio_ss.add(files('virtio.c')) diff --git a/hw/virtio/virtio-stub.c b/hw/virtio/virtio-stub.c new file mode 100644 index 0000000..d4a88f5 --- /dev/null +++ b/hw/virtio/virtio-stub.c @@ -0,0 +1,14 @@ +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qapi/qapi-commands-virtio.h" + +static void *qmp_virtio_unsupported(Error **errp) +{ + error_setg(errp, "Virtio is disabled"); + return NULL; +} + +VirtioInfoList *qmp_x_debug_query_virtio(Error **errp) +{ + return qmp_virtio_unsupported(errp); +} diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 874377f..f3fc1bb 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -13,6 +13,8 @@ #include "qemu/osdep.h" #include "qapi/error.h" +#include "qapi/qapi-commands-virtio.h" +#include "qapi/qapi-visit-virtio.h" #include "cpu.h" #include "trace.h" #include "qemu/error-report.h" @@ -29,6 +31,8 @@ #include "sysemu/runstate.h" #include "standard-headers/linux/virtio_ids.h" +static QTAILQ_HEAD(, VirtIODevice) virtio_list; + /* * The alignment to use between consumer and producer parts of vring. * x86 pagesize again. This is the default, used by transports like PCI @@ -3672,6 +3676,7 @@ static void virtio_device_realize(DeviceState *dev, Error **errp) vdev->listener.commit = virtio_memory_listener_commit; memory_listener_register(&vdev->listener, vdev->dma_as); + QTAILQ_INSERT_TAIL(&virtio_list, vdev, next); } static void virtio_device_unrealize(DeviceState *dev) @@ -3686,6 +3691,7 @@ static void virtio_device_unrealize(DeviceState *dev) vdc->unrealize(dev); } + QTAILQ_REMOVE(&virtio_list, vdev, next); g_free(vdev->bus_name); vdev->bus_name = NULL; } @@ -3859,6 +3865,8 @@ static void virtio_device_class_init(ObjectClass *klass, void *data) vdc->stop_ioeventfd = virtio_device_stop_ioeventfd_impl; vdc->legacy_features |= VIRTIO_LEGACY_FEATURES; + + QTAILQ_INIT(&virtio_list); } bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev) @@ -3869,6 +3877,25 @@ bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev) return virtio_bus_ioeventfd_enabled(vbus); } +VirtioInfoList *qmp_x_debug_query_virtio(Error **errp) +{ + VirtioInfoList *list = NULL; + VirtioInfoList *node; + VirtIODevice *vdev; + + QTAILQ_FOREACH(vdev, &virtio_list, next) { + DeviceState *dev = DEVICE(vdev); + node = g_new0(VirtioInfoList, 1); + node->value = g_new(VirtioInfo, 1); + node->value->path = g_strdup(dev->canonical_path); + node->value->type = qapi_enum_parse(&VirtioType_lookup, vdev->name, + VIRTIO_TYPE_UNKNOWN, NULL); + QAPI_LIST_PREPEND(list, node->value); + } + + return list; +} + static const TypeInfo virtio_device_info = { .name = TYPE_VIRTIO_DEVICE, .parent = TYPE_DEVICE, diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 8bab9cf..f7da326 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -108,6 +108,7 @@ struct VirtIODevice bool use_guest_notifier_mask; AddressSpace *dma_as; QLIST_HEAD(, VirtQueue) *vector_queues; + QTAILQ_ENTRY(VirtIODevice) next; }; struct VirtioDeviceClass { diff --git a/qapi/meson.build b/qapi/meson.build index 376f4ce..4e1da08 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -44,6 +44,7 @@ qapi_all_modules = [ 'sockets', 'trace', 'transaction', + 'virtio', 'yank', ] if have_system diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index 4912b97..0c89789 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -91,5 +91,6 @@ { 'include': 'misc.json' } { 'include': 'misc-target.json' } { 'include': 'audio.json' } +{ 'include': 'virtio.json' } { 'include': 'acpi.json' } { 'include': 'pci.json' } diff --git a/qapi/virtio.json b/qapi/virtio.json new file mode 100644 index 0000000..804adbe --- /dev/null +++ b/qapi/virtio.json @@ -0,0 +1,72 @@ +## +# = Virtio devices +## + +## +# @VirtioType: +# +# An enumeration of Virtio device types. +# +# Since: 6.1 +## +{ 'enum': 'VirtioType', + 'data': [ 'unknown', 'virtio-net', 'virtio-blk', 'virtio-console', + 'virtio-rng', 'virtio-balloon', 'virtio-iomem', 'virtio-rpmsg', + 'virtio-scsi', 'virtio-9p', 'virtio-mac80211-wlan', + 'virtio-serial', 'virtio-caif', 'virtio-memory-balloon', + 'unknown-14', 'unknown-15', 'virtio-gpu', 'virtio-clock', + 'virtio-input', 'vhost-vsock', 'virtio-crypto', 'virtio-signal-dist', + 'virtio-pstore', 'virtio-iommu', 'virtio-mem', 'unknown-25', + 'vhost-user-fs', 'virtio-pmem', 'unknown-28', 'virtio-mac80211-hwsim' ] +} + +## +# @VirtioInfo: +# +# Information about a given VirtIODevice +# +# @path: VirtIO device canonical path. +# +# @type: VirtIO device type. +# +# Since: 6.1 +# +## +{ 'struct': 'VirtioInfo', + 'data': { + 'path': 'str', + 'type': 'VirtioType' + } +} + +## +# @x-debug-query-virtio: +# +# Return the list of all VirtIO devices +# +# Returns: list of @VirtioInfo +# +# Since: 6.1 +# +# Example: +# +# -> { "execute": "x-debug-query-virtio" } +# <- { "return": [ +# { +# "path": "/machine/peripheral-anon/device[3]/virtio-backend", +# "type": "virtio-net" +# }, +# { +# "path": "/machine/peripheral-anon/device[1]/virtio-backend", +# "type": "virtio-serial" +# }, +# { +# "path": "/machine/peripheral-anon/device[0]/virtio-backend", +# "type": "virtio-blk" +# } +# ] +# } +# +## + +{ 'command': 'x-debug-query-virtio', 'returns': ['VirtioInfo'] } diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c index c98b78d..b2cf0628 100644 --- a/tests/qtest/qmp-cmd-test.c +++ b/tests/qtest/qmp-cmd-test.c @@ -95,6 +95,7 @@ static bool query_is_ignored(const char *cmd) "query-gic-capabilities", /* arm */ /* Success depends on target-specific build configuration: */ "query-pci", /* CONFIG_PCI */ + "x-debug-query-virtio", /* CONFIG_VIRTIO */ /* Success depends on launching SEV guest */ "query-sev-launch-measure", /* Success depends on Host or Hypervisor SEV support */