[PATCH V2] virtio-pci: fix queue_enable write

Jason Wang posted 1 patch 3 years, 10 months ago
Test docker-mingw@fedora passed
Test checkpatch passed
Test asan passed
Test docker-quick@centos7 passed
Test FreeBSD passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20200610054351.15811-1-jasowang@redhat.com
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>
hw/virtio/virtio-pci.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
[PATCH V2] virtio-pci: fix queue_enable write
Posted by Jason Wang 3 years, 10 months ago
Spec said: The driver uses this to selectively prevent the device from
executing requests from this virtqueue. 1 - enabled; 0 - disabled.

Though write 0 to queue_enable is forbidden by the spec, we should not
assume that the value is 1.

Fix this by ignore the write value other than 1.

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
Changes from V1:
- fix typo
- warn wrong value through virtio_error
---
 hw/virtio/virtio-pci.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index d028c17c24..7bc8c1c056 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1273,16 +1273,20 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
         virtio_queue_set_vector(vdev, vdev->queue_sel, val);
         break;
     case VIRTIO_PCI_COMMON_Q_ENABLE:
-        virtio_queue_set_num(vdev, vdev->queue_sel,
-                             proxy->vqs[vdev->queue_sel].num);
-        virtio_queue_set_rings(vdev, vdev->queue_sel,
+        if (val == 1) {
+            virtio_queue_set_num(vdev, vdev->queue_sel,
+                                 proxy->vqs[vdev->queue_sel].num);
+            virtio_queue_set_rings(vdev, vdev->queue_sel,
                        ((uint64_t)proxy->vqs[vdev->queue_sel].desc[1]) << 32 |
                        proxy->vqs[vdev->queue_sel].desc[0],
                        ((uint64_t)proxy->vqs[vdev->queue_sel].avail[1]) << 32 |
                        proxy->vqs[vdev->queue_sel].avail[0],
                        ((uint64_t)proxy->vqs[vdev->queue_sel].used[1]) << 32 |
                        proxy->vqs[vdev->queue_sel].used[0]);
-        proxy->vqs[vdev->queue_sel].enabled = 1;
+            proxy->vqs[vdev->queue_sel].enabled = 1;
+        } else {
+            virtio_error(vdev, "wrong value for queue_enable %"PRIx64, val);
+        }
         break;
     case VIRTIO_PCI_COMMON_Q_DESCLO:
         proxy->vqs[vdev->queue_sel].desc[0] = val;
-- 
2.20.1


Re: [PATCH V2] virtio-pci: fix queue_enable write
Posted by Stefano Garzarella 3 years, 10 months ago
On Wed, Jun 10, 2020 at 01:43:51PM +0800, Jason Wang wrote:
> Spec said: The driver uses this to selectively prevent the device from
> executing requests from this virtqueue. 1 - enabled; 0 - disabled.
> 
> Though write 0 to queue_enable is forbidden by the spec, we should not
> assume that the value is 1.
> 
> Fix this by ignore the write value other than 1.
> 
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> Changes from V1:
> - fix typo
> - warn wrong value through virtio_error
> ---
>  hw/virtio/virtio-pci.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index d028c17c24..7bc8c1c056 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -1273,16 +1273,20 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
>          virtio_queue_set_vector(vdev, vdev->queue_sel, val);
>          break;
>      case VIRTIO_PCI_COMMON_Q_ENABLE:
> -        virtio_queue_set_num(vdev, vdev->queue_sel,
> -                             proxy->vqs[vdev->queue_sel].num);
> -        virtio_queue_set_rings(vdev, vdev->queue_sel,
> +        if (val == 1) {

Does it have to be 1 or can it be any value other than 0?

Thanks,
Stefano

> +            virtio_queue_set_num(vdev, vdev->queue_sel,
> +                                 proxy->vqs[vdev->queue_sel].num);
> +            virtio_queue_set_rings(vdev, vdev->queue_sel,
>                         ((uint64_t)proxy->vqs[vdev->queue_sel].desc[1]) << 32 |
>                         proxy->vqs[vdev->queue_sel].desc[0],
>                         ((uint64_t)proxy->vqs[vdev->queue_sel].avail[1]) << 32 |
>                         proxy->vqs[vdev->queue_sel].avail[0],
>                         ((uint64_t)proxy->vqs[vdev->queue_sel].used[1]) << 32 |
>                         proxy->vqs[vdev->queue_sel].used[0]);
> -        proxy->vqs[vdev->queue_sel].enabled = 1;
> +            proxy->vqs[vdev->queue_sel].enabled = 1;
> +        } else {
> +            virtio_error(vdev, "wrong value for queue_enable %"PRIx64, val);
> +        }
>          break;
>      case VIRTIO_PCI_COMMON_Q_DESCLO:
>          proxy->vqs[vdev->queue_sel].desc[0] = val;
> -- 
> 2.20.1
> 
> 


Re: [PATCH V2] virtio-pci: fix queue_enable write
Posted by Michael S. Tsirkin 3 years, 10 months ago
On Wed, Jun 10, 2020 at 10:57:26AM +0200, Stefano Garzarella wrote:
> On Wed, Jun 10, 2020 at 01:43:51PM +0800, Jason Wang wrote:
> > Spec said: The driver uses this to selectively prevent the device from
> > executing requests from this virtqueue. 1 - enabled; 0 - disabled.
> > 
> > Though write 0 to queue_enable is forbidden by the spec, we should not
> > assume that the value is 1.
> > 
> > Fix this by ignore the write value other than 1.
> > 
> > Signed-off-by: Jason Wang <jasowang@redhat.com>
> > ---
> > Changes from V1:
> > - fix typo
> > - warn wrong value through virtio_error
> > ---
> >  hw/virtio/virtio-pci.c | 12 ++++++++----
> >  1 file changed, 8 insertions(+), 4 deletions(-)
> > 
> > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> > index d028c17c24..7bc8c1c056 100644
> > --- a/hw/virtio/virtio-pci.c
> > +++ b/hw/virtio/virtio-pci.c
> > @@ -1273,16 +1273,20 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
> >          virtio_queue_set_vector(vdev, vdev->queue_sel, val);
> >          break;
> >      case VIRTIO_PCI_COMMON_Q_ENABLE:
> > -        virtio_queue_set_num(vdev, vdev->queue_sel,
> > -                             proxy->vqs[vdev->queue_sel].num);
> > -        virtio_queue_set_rings(vdev, vdev->queue_sel,
> > +        if (val == 1) {
> 
> Does it have to be 1 or can it be any value other than 0?
> 
> Thanks,
> Stefano

spec says 1

> > +            virtio_queue_set_num(vdev, vdev->queue_sel,
> > +                                 proxy->vqs[vdev->queue_sel].num);
> > +            virtio_queue_set_rings(vdev, vdev->queue_sel,
> >                         ((uint64_t)proxy->vqs[vdev->queue_sel].desc[1]) << 32 |
> >                         proxy->vqs[vdev->queue_sel].desc[0],
> >                         ((uint64_t)proxy->vqs[vdev->queue_sel].avail[1]) << 32 |
> >                         proxy->vqs[vdev->queue_sel].avail[0],
> >                         ((uint64_t)proxy->vqs[vdev->queue_sel].used[1]) << 32 |
> >                         proxy->vqs[vdev->queue_sel].used[0]);
> > -        proxy->vqs[vdev->queue_sel].enabled = 1;
> > +            proxy->vqs[vdev->queue_sel].enabled = 1;
> > +        } else {
> > +            virtio_error(vdev, "wrong value for queue_enable %"PRIx64, val);
> > +        }
> >          break;
> >      case VIRTIO_PCI_COMMON_Q_DESCLO:
> >          proxy->vqs[vdev->queue_sel].desc[0] = val;
> > -- 
> > 2.20.1
> > 
> > 


Re: [PATCH V2] virtio-pci: fix queue_enable write
Posted by Stefano Garzarella 3 years, 10 months ago
On Wed, Jun 10, 2020 at 05:42:54AM -0400, Michael S. Tsirkin wrote:
> On Wed, Jun 10, 2020 at 10:57:26AM +0200, Stefano Garzarella wrote:
> > On Wed, Jun 10, 2020 at 01:43:51PM +0800, Jason Wang wrote:
> > > Spec said: The driver uses this to selectively prevent the device from
> > > executing requests from this virtqueue. 1 - enabled; 0 - disabled.
> > > 
> > > Though write 0 to queue_enable is forbidden by the spec, we should not
> > > assume that the value is 1.
> > > 
> > > Fix this by ignore the write value other than 1.
> > > 
> > > Signed-off-by: Jason Wang <jasowang@redhat.com>
> > > ---
> > > Changes from V1:
> > > - fix typo
> > > - warn wrong value through virtio_error
> > > ---
> > >  hw/virtio/virtio-pci.c | 12 ++++++++----
> > >  1 file changed, 8 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> > > index d028c17c24..7bc8c1c056 100644
> > > --- a/hw/virtio/virtio-pci.c
> > > +++ b/hw/virtio/virtio-pci.c
> > > @@ -1273,16 +1273,20 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
> > >          virtio_queue_set_vector(vdev, vdev->queue_sel, val);
> > >          break;
> > >      case VIRTIO_PCI_COMMON_Q_ENABLE:
> > > -        virtio_queue_set_num(vdev, vdev->queue_sel,
> > > -                             proxy->vqs[vdev->queue_sel].num);
> > > -        virtio_queue_set_rings(vdev, vdev->queue_sel,
> > > +        if (val == 1) {
> > 
> > Does it have to be 1 or can it be any value other than 0?
> > 
> > Thanks,
> > Stefano
> 
> spec says 1

I was confused by "The driver MUST NOT write a 0 to queue_enable.",
interpreting it as "can write anything other than 0".

But as Jason also wrote in the commit message, the driver should write
1 to enable, so

Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>

Thanks,
Stefano


Re: [PATCH V2] virtio-pci: fix queue_enable write
Posted by Jason Wang 3 years, 10 months ago
On 2020/6/10 下午5:52, Stefano Garzarella wrote:
> On Wed, Jun 10, 2020 at 05:42:54AM -0400, Michael S. Tsirkin wrote:
>> On Wed, Jun 10, 2020 at 10:57:26AM +0200, Stefano Garzarella wrote:
>>> On Wed, Jun 10, 2020 at 01:43:51PM +0800, Jason Wang wrote:
>>>> Spec said: The driver uses this to selectively prevent the device from
>>>> executing requests from this virtqueue. 1 - enabled; 0 - disabled.
>>>>
>>>> Though write 0 to queue_enable is forbidden by the spec, we should not
>>>> assume that the value is 1.
>>>>
>>>> Fix this by ignore the write value other than 1.
>>>>
>>>> Signed-off-by: Jason Wang <jasowang@redhat.com>
>>>> ---
>>>> Changes from V1:
>>>> - fix typo
>>>> - warn wrong value through virtio_error
>>>> ---
>>>>   hw/virtio/virtio-pci.c | 12 ++++++++----
>>>>   1 file changed, 8 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
>>>> index d028c17c24..7bc8c1c056 100644
>>>> --- a/hw/virtio/virtio-pci.c
>>>> +++ b/hw/virtio/virtio-pci.c
>>>> @@ -1273,16 +1273,20 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
>>>>           virtio_queue_set_vector(vdev, vdev->queue_sel, val);
>>>>           break;
>>>>       case VIRTIO_PCI_COMMON_Q_ENABLE:
>>>> -        virtio_queue_set_num(vdev, vdev->queue_sel,
>>>> -                             proxy->vqs[vdev->queue_sel].num);
>>>> -        virtio_queue_set_rings(vdev, vdev->queue_sel,
>>>> +        if (val == 1) {
>>> Does it have to be 1 or can it be any value other than 0?
>>>
>>> Thanks,
>>> Stefano
>> spec says 1
> I was confused by "The driver MUST NOT write a 0 to queue_enable.",
> interpreting it as "can write anything other than 0".


Yes, the spec is unclear about what happens if we write a value other 
than 0 or 1.

Maybe we should clarify that only 1 is allowed. Or writing value other 
than 1 may cause unexpected result.


>
> But as Jason also wrote in the commit message, the driver should write
> 1 to enable, so
>
> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>


Thanks


>
> Thanks,
> Stefano
>


Re: [PATCH V2] virtio-pci: fix queue_enable write
Posted by Stefan Hajnoczi 3 years, 10 months ago
On Wed, Jun 10, 2020 at 01:43:51PM +0800, Jason Wang wrote:
> Spec said: The driver uses this to selectively prevent the device from
> executing requests from this virtqueue. 1 - enabled; 0 - disabled.
> 
> Though write 0 to queue_enable is forbidden by the spec, we should not
> assume that the value is 1.
> 
> Fix this by ignore the write value other than 1.
> 
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> Changes from V1:
> - fix typo
> - warn wrong value through virtio_error
> ---
>  hw/virtio/virtio-pci.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>