From: "Michael S. Tsirkin" <mst@redhat.com>
To: Gerd Hoffmann <kraxel@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
"open list:virtio-blk" <qemu-block@nongnu.org>,
qemu-devel@nongnu.org, Amit Shah <amit.shah@redhat.com>,
"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>,
Stefan Hajnoczi <stefanha@redhat.com>,
Cornelia Huck <cornelia.huck@de.ibm.com>,
Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v2] virtio: make features 64bit wide
Date: Fri, 29 May 2015 16:53:31 +0200 [thread overview]
Message-ID: <20150529165138-mutt-send-email-mst@redhat.com> (raw)
In-Reply-To: <1432885880-9847-1-git-send-email-kraxel@redhat.com>
On Fri, May 29, 2015 at 09:51:20AM +0200, Gerd Hoffmann wrote:
> Make features 64bit wide everywhere. Exception: command line flags
> remain 32bit and are copyed into the lower 32 host_features at
> initialization time.
>
> On migration a full 64bit guest_features field is sent if one of the
> high bits is set, additionally to the lower 32bit guest_features field
> which must stay for compatibility reasons. That way we send the lower
> 32 feature bits twice, but that way the code is simpler because we don't
> have to split and compose the 64bit features into two 32bit fields.
>
> This depends on "move host_features" patch by cornelia.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Thanks, this is very close to what I had in mind.
Question: why do we need the feature_flags field?
What's wrong with setting bits in host_features directly?
> ---
> hw/9pfs/virtio-9p-device.c | 2 +-
> hw/block/virtio-blk.c | 2 +-
> hw/char/virtio-serial-bus.c | 2 +-
> hw/net/virtio-net.c | 18 ++++++++-------
> hw/scsi/vhost-scsi.c | 4 ++--
> hw/scsi/virtio-scsi.c | 4 ++--
> hw/virtio/virtio-balloon.c | 2 +-
> hw/virtio/virtio-rng.c | 2 +-
> hw/virtio/virtio.c | 54 +++++++++++++++++++++++++++++++++++++++------
> include/hw/virtio/virtio.h | 21 +++++++++---------
> 10 files changed, 77 insertions(+), 34 deletions(-)
>
> diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
> index 30492ec..60f9ff9 100644
> --- a/hw/9pfs/virtio-9p-device.c
> +++ b/hw/9pfs/virtio-9p-device.c
> @@ -21,7 +21,7 @@
> #include "virtio-9p-coth.h"
> #include "hw/virtio/virtio-access.h"
>
> -static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
> +static uint64_t virtio_9p_get_features(VirtIODevice *vdev, uint64_t features)
> {
> virtio_add_feature(&features, VIRTIO_9P_MOUNT_TAG);
> return features;
> diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
> index e6afe97..cd539aa 100644
> --- a/hw/block/virtio-blk.c
> +++ b/hw/block/virtio-blk.c
> @@ -718,7 +718,7 @@ static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
> aio_context_release(blk_get_aio_context(s->blk));
> }
>
> -static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
> +static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features)
> {
> VirtIOBlock *s = VIRTIO_BLK(vdev);
>
> diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
> index 6e2ad82..95be9fc 100644
> --- a/hw/char/virtio-serial-bus.c
> +++ b/hw/char/virtio-serial-bus.c
> @@ -498,7 +498,7 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
> }
> }
>
> -static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
> +static uint64_t get_features(VirtIODevice *vdev, uint64_t features)
> {
> VirtIOSerial *vser;
>
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 3af6faf..b21ef6b 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -435,7 +435,7 @@ static void virtio_net_set_queues(VirtIONet *n)
>
> static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue);
>
> -static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
> +static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features)
> {
> VirtIONet *n = VIRTIO_NET(vdev);
> NetClientState *nc = qemu_get_queue(n->nic);
> @@ -468,9 +468,9 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
> return vhost_net_get_features(get_vhost_net(nc->peer), features);
> }
>
> -static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
> +static uint64_t virtio_net_bad_features(VirtIODevice *vdev)
> {
> - uint32_t features = 0;
> + uint64_t features = 0;
>
> /* Linux kernel 2.6.25. It understood MAC (as everyone must),
> * but also these: */
> @@ -1032,10 +1032,12 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
> if (i == 0)
> return -1;
> error_report("virtio-net unexpected empty queue: "
> - "i %zd mergeable %d offset %zd, size %zd, "
> - "guest hdr len %zd, host hdr len %zd guest features 0x%x",
> - i, n->mergeable_rx_bufs, offset, size,
> - n->guest_hdr_len, n->host_hdr_len, vdev->guest_features);
> + "i %zd mergeable %d offset %zd, size %zd, "
> + "guest hdr len %zd, host hdr len %zd "
> + "guest features 0x%" PRIx64,
> + i, n->mergeable_rx_bufs, offset, size,
> + n->guest_hdr_len, n->host_hdr_len,
> + vdev->guest_features);
> exit(1);
> }
>
> @@ -1549,7 +1551,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
> vdev, idx, mask);
> }
>
> -static void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features)
> +static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
> {
> int i, config_size = 0;
> virtio_add_feature(&host_features, VIRTIO_NET_F_MAC);
> diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
> index 335f442..9c76486 100644
> --- a/hw/scsi/vhost-scsi.c
> +++ b/hw/scsi/vhost-scsi.c
> @@ -151,8 +151,8 @@ static void vhost_scsi_stop(VHostSCSI *s)
> vhost_dev_disable_notifiers(&s->dev, vdev);
> }
>
> -static uint32_t vhost_scsi_get_features(VirtIODevice *vdev,
> - uint32_t features)
> +static uint64_t vhost_scsi_get_features(VirtIODevice *vdev,
> + uint64_t features)
> {
> VHostSCSI *s = VHOST_SCSI(vdev);
>
> diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
> index e242fef..36ae66e 100644
> --- a/hw/scsi/virtio-scsi.c
> +++ b/hw/scsi/virtio-scsi.c
> @@ -628,8 +628,8 @@ static void virtio_scsi_set_config(VirtIODevice *vdev,
> vs->cdb_size = virtio_ldl_p(vdev, &scsiconf->cdb_size);
> }
>
> -static uint32_t virtio_scsi_get_features(VirtIODevice *vdev,
> - uint32_t requested_features)
> +static uint64_t virtio_scsi_get_features(VirtIODevice *vdev,
> + uint64_t requested_features)
> {
> VirtIOSCSI *s = VIRTIO_SCSI(vdev);
>
> diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
> index 484c3c3..734f35b 100644
> --- a/hw/virtio/virtio-balloon.c
> +++ b/hw/virtio/virtio-balloon.c
> @@ -310,7 +310,7 @@ static void virtio_balloon_set_config(VirtIODevice *vdev,
> trace_virtio_balloon_set_config(dev->actual, oldactual);
> }
>
> -static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)
> +static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f)
> {
> f |= (1 << VIRTIO_BALLOON_F_STATS_VQ);
> return f;
> diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
> index 06e7178..420c39f 100644
> --- a/hw/virtio/virtio-rng.c
> +++ b/hw/virtio/virtio-rng.c
> @@ -99,7 +99,7 @@ static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
> virtio_rng_process(vrng);
> }
>
> -static uint32_t get_features(VirtIODevice *vdev, uint32_t f)
> +static uint64_t get_features(VirtIODevice *vdev, uint64_t f)
> {
> return f;
> }
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 96d9c6a..4c2911a 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -893,6 +893,13 @@ static bool virtio_device_endian_needed(void *opaque)
> return vdev->device_endian != virtio_default_endian();
> }
>
> +static bool virtio_64bit_features_needed(void *opaque)
> +{
> + VirtIODevice *vdev = opaque;
> +
> + return (vdev->host_features >> 32) != 0;
> +}
> +
> static const VMStateDescription vmstate_virtio_device_endian = {
> .name = "virtio/device_endian",
> .version_id = 1,
> @@ -903,6 +910,16 @@ static const VMStateDescription vmstate_virtio_device_endian = {
> }
> };
>
> +static const VMStateDescription vmstate_virtio_64bit_features = {
> + .name = "virtio/64bit_features",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .fields = (VMStateField[]) {
> + VMSTATE_UINT64(guest_features, VirtIODevice),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> static const VMStateDescription vmstate_virtio = {
> .name = "virtio",
> .version_id = 1,
> @@ -916,6 +933,10 @@ static const VMStateDescription vmstate_virtio = {
> .vmsd = &vmstate_virtio_device_endian,
> .needed = &virtio_device_endian_needed
> },
> + {
> + .vmsd = &vmstate_virtio_64bit_features,
> + .needed = &virtio_64bit_features_needed
> + },
> { 0 }
> }
> };
> @@ -925,6 +946,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
> VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
> + uint32_t guest_features_lo = (vdev->guest_features & 0xffffffff);
> int i;
>
> if (k->save_config) {
> @@ -934,7 +956,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> qemu_put_8s(f, &vdev->status);
> qemu_put_8s(f, &vdev->isr);
> qemu_put_be16s(f, &vdev->queue_sel);
> - qemu_put_be32s(f, &vdev->guest_features);
> + qemu_put_be32s(f, &guest_features_lo);
> qemu_put_be32(f, vdev->config_len);
> qemu_put_buffer(f, vdev->config, vdev->config_len);
>
> @@ -1011,11 +1033,6 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
> }
> qemu_get_be32s(f, &features);
>
> - if (virtio_set_features(vdev, features) < 0) {
> - error_report("Features 0x%x unsupported. Allowed features: 0x%x",
> - features, vdev->host_features);
> - return -1;
> - }
> config_len = qemu_get_be32(f);
>
> /*
> @@ -1081,6 +1098,28 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
> vdev->device_endian = virtio_default_endian();
> }
>
> + if (virtio_64bit_features_needed(vdev)) {
> + /*
> + * Subsection load filled vdev->guest_features. Run them
> + * through virtio_set_features to sanity-check them against
> + * host_features.
> + */
> + uint64_t features64 = vdev->guest_features;
> + if (virtio_set_features(vdev, features64) < 0) {
> + error_report("Features 0x%" PRIx64 " unsupported. "
> + "Allowed features: 0x%" PRIx64,
> + features64, vdev->host_features);
> + return -1;
> + }
> + } else {
> + if (virtio_set_features(vdev, features) < 0) {
> + error_report("Features 0x%x unsupported. "
> + "Allowed features: 0x%" PRIx64,
> + features, vdev->host_features);
> + return -1;
> + }
> + }
> +
> for (i = 0; i < num; i++) {
> if (vdev->vq[i].pa) {
> uint16_t nheads;
> @@ -1176,6 +1215,7 @@ void virtio_init(VirtIODevice *vdev, const char *name,
> vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change,
> vdev);
> vdev->device_endian = virtio_default_endian();
> + vdev->host_features = vdev->feature_flags;
> }
>
> hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n)
> @@ -1347,7 +1387,7 @@ static void virtio_device_unrealize(DeviceState *dev, Error **errp)
> }
>
> static Property virtio_properties[] = {
> - DEFINE_VIRTIO_COMMON_FEATURES(VirtIODevice, host_features),
> + DEFINE_VIRTIO_COMMON_FEATURES(VirtIODevice, feature_flags),
> DEFINE_PROP_END_OF_LIST(),
> };
>
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index b620da5..261a208 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -73,8 +73,9 @@ struct VirtIODevice
> uint8_t status;
> uint8_t isr;
> uint16_t queue_sel;
> - uint32_t guest_features;
> - uint32_t host_features;
> + uint64_t guest_features;
> + uint64_t host_features;
> + uint32_t feature_flags;
> size_t config_len;
> void *config;
> uint16_t config_vector;
> @@ -96,8 +97,8 @@ typedef struct VirtioDeviceClass {
> /* This is what a VirtioDevice must implement */
> DeviceRealize realize;
> DeviceUnrealize unrealize;
> - uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
> - uint32_t (*bad_features)(VirtIODevice *vdev);
> + uint64_t (*get_features)(VirtIODevice *vdev, uint64_t requested_features);
> + uint64_t (*bad_features)(VirtIODevice *vdev);
> void (*set_features)(VirtIODevice *vdev, uint32_t val);
> void (*get_config)(VirtIODevice *vdev, uint8_t *config);
> void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
> @@ -223,21 +224,21 @@ void virtio_irq(VirtQueue *vq);
> VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
> VirtQueue *virtio_vector_next_queue(VirtQueue *vq);
>
> -static inline void virtio_add_feature(uint32_t *features, unsigned int fbit)
> +static inline void virtio_add_feature(uint64_t *features, unsigned int fbit)
> {
> - assert(fbit < 32);
> + assert(fbit < 64);
> *features |= (1 << fbit);
> }
>
> -static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit)
> +static inline void virtio_clear_feature(uint64_t *features, unsigned int fbit)
> {
> - assert(fbit < 32);
> + assert(fbit < 64);
> *features &= ~(1 << fbit);
> }
>
> -static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit)
> +static inline bool __virtio_has_feature(uint64_t features, unsigned int fbit)
> {
> - assert(fbit < 32);
> + assert(fbit < 64);
> return !!(features & (1 << fbit));
> }
>
> --
> 1.8.3.1
next prev parent reply other threads:[~2015-05-29 14:53 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-29 7:51 [Qemu-devel] [PATCH v2] virtio: make features 64bit wide Gerd Hoffmann
2015-05-29 14:53 ` Michael S. Tsirkin [this message]
2015-06-01 7:23 ` Gerd Hoffmann
2015-06-01 7:29 ` Michael S. Tsirkin
2015-05-29 16:46 ` [Qemu-devel] [Qemu-block] " Eric Blake
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150529165138-mutt-send-email-mst@redhat.com \
--to=mst@redhat.com \
--cc=amit.shah@redhat.com \
--cc=aneesh.kumar@linux.vnet.ibm.com \
--cc=cornelia.huck@de.ibm.com \
--cc=kraxel@redhat.com \
--cc=kwolf@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.