All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-devel@nongnu.org, agraf@suse.de
Subject: Re: [Qemu-devel] [PATCH 1.0] virtio: add and use virtio_set_features
Date: Thu, 24 Nov 2011 18:42:04 +0200	[thread overview]
Message-ID: <20111124164203.GE26770@redhat.com> (raw)
In-Reply-To: <1322137732-30840-1-git-send-email-pbonzini@redhat.com>

On Thu, Nov 24, 2011 at 01:28:52PM +0100, Paolo Bonzini wrote:
> vdev->guest_features is not masking features that are not supported by
> the guest.  Fix this by introducing a common wrapper to be used by all
> virtio bus implementations.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Yes, while I can't point to a specific problem
I think it's a very good idea to avoid invalid guest
feature values.

And removing code duplication is good too.

A minor comment below

> ---
>  hw/s390-virtio-bus.c |    5 +----
>  hw/syborg_virtio.c   |    4 +---
>  hw/virtio-pci.c      |    9 ++-------
>  hw/virtio.c          |   24 ++++++++++++++++++------
>  hw/virtio.h          |    1 +
>  5 files changed, 23 insertions(+), 20 deletions(-)
> 
> diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
> index 0ce6406..c4b9a99 100644
> --- a/hw/s390-virtio-bus.c
> +++ b/hw/s390-virtio-bus.c
> @@ -254,10 +254,7 @@ void s390_virtio_device_update_status(VirtIOS390Device *dev)
>      /* Update guest supported feature bitmap */
>  
>      features = bswap32(ldl_be_phys(dev->feat_offs));
> -    if (vdev->set_features) {
> -        vdev->set_features(vdev, features);
> -    }
> -    vdev->guest_features = features;
> +    virtio_set_features(vdev, features);
>  }
>  
>  VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus)
> diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c
> index 00c7be8..6de952c 100644
> --- a/hw/syborg_virtio.c
> +++ b/hw/syborg_virtio.c
> @@ -131,9 +131,7 @@ static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset,
>      }
>      switch (offset >> 2) {
>      case SYBORG_VIRTIO_GUEST_FEATURES:
> -        if (vdev->set_features)
> -            vdev->set_features(vdev, value);
> -        vdev->guest_features = value;
> +        virtio_set_features(vdev, value);
>          break;
>      case SYBORG_VIRTIO_QUEUE_BASE:
>          if (value == 0)
> diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
> index ca5923c..64c6a94 100644
> --- a/hw/virtio-pci.c
> +++ b/hw/virtio-pci.c
> @@ -285,14 +285,9 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
>      case VIRTIO_PCI_GUEST_FEATURES:
>  	/* Guest does not negotiate properly?  We have to assume nothing. */
>  	if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
> -	    if (vdev->bad_features)
> -		val = proxy->host_features & vdev->bad_features(vdev);
> -	    else
> -		val = 0;
> +            val = vdev->bad_features ? vdev->bad_features(vdev) : 0;
>  	}
> -        if (vdev->set_features)
> -            vdev->set_features(vdev, val);
> -        vdev->guest_features = val;
> +        virtio_set_features(vdev, val);
>          break;
>      case VIRTIO_PCI_QUEUE_PFN:
>          pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
> diff --git a/hw/virtio.c b/hw/virtio.c
> index 7011b5b..81ecc40 100644
> --- a/hw/virtio.c
> +++ b/hw/virtio.c
> @@ -763,12 +763,25 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
>      }
>  }
>  
> +int virtio_set_features(VirtIODevice *vdev, uint32_t val)
> +{
> +    uint32_t supported_features =
> +        vdev->binding->get_features(vdev->binding_opaque);
> +    bool bad = (val & ~supported_features) != 0;
> +
> +    val &= supported_features;
> +    if (vdev->set_features) {
> +        vdev->set_features(vdev, val);
> +    }
> +    vdev->guest_features = val;
> +    return bad ? -1 : 0;
> +}
> +

Most users ignore the return value anyway,
and virtio_load needs to look at supported features
mask for the diagnostic anyway. So let's use virtio_set_features
void.

As a nice side effect, virtio_load can do it's checks
before anything is set, only set features if it's ok.

>  int virtio_load(VirtIODevice *vdev, QEMUFile *f)
>  {
>      int num, i, ret;
>      uint32_t features;
> -    uint32_t supported_features =
> -        vdev->binding->get_features(vdev->binding_opaque);
> +    uint32_t supported_features;
>  
>      if (vdev->binding->load_config) {
>          ret = vdev->binding->load_config(vdev->binding_opaque, f);
> @@ -780,14 +793,13 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
>      qemu_get_8s(f, &vdev->isr);
>      qemu_get_be16s(f, &vdev->queue_sel);
>      qemu_get_be32s(f, &features);
> -    if (features & ~supported_features) {
> +
> +    if (virtio_set_features(vdev, features) < 0) {
> +        supported_features = vdev->binding->get_features(vdev->binding_opaque);
>          error_report("Features 0x%x unsupported. Allowed features: 0x%x",
>                       features, supported_features);
>          return -1;
>      }
> -    if (vdev->set_features)
> -        vdev->set_features(vdev, features);
> -    vdev->guest_features = features;
>      vdev->config_len = qemu_get_be32(f);
>      qemu_get_buffer(f, vdev->config, vdev->config_len);
>  
> diff --git a/hw/virtio.h b/hw/virtio.h
> index 2d18209..25f5564 100644
> --- a/hw/virtio.h
> +++ b/hw/virtio.h
> @@ -185,6 +185,7 @@ void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector);
>  void virtio_set_status(VirtIODevice *vdev, uint8_t val);
>  void virtio_reset(void *opaque);
>  void virtio_update_irq(VirtIODevice *vdev);
> +int virtio_set_features(VirtIODevice *vdev, uint32_t val);
>  
>  void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
>                          void *opaque);
> -- 
> 1.7.7.1

  reply	other threads:[~2011-11-24 16:40 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-11-24 12:28 [Qemu-devel] [PATCH 1.0] virtio: add and use virtio_set_features Paolo Bonzini
2011-11-24 16:42 ` Michael S. Tsirkin [this message]
2011-11-24 16:49   ` Paolo Bonzini
2011-11-24 17:55     ` Michael S. Tsirkin
2011-11-25  8:23       ` Paolo Bonzini
2011-11-26 20:45         ` Michael S. Tsirkin
2011-11-28 22:38         ` Anthony Liguori

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=20111124164203.GE26770@redhat.com \
    --to=mst@redhat.com \
    --cc=agraf@suse.de \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /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.