Message ID | 1479977767-14027-1-git-send-email-thuth@redhat.com |
---|---|
State | Accepted |
Headers | show |
On 24/11/16 19:56, Thomas Huth wrote: > Virtio needs the descriptors ordered: All descriptors for buffers that > contain data that should go *to* the device have to be put into the > queue first. The descriptors for buffers that read *from* the device > have to be sorted in last. For SCSI WRITE commands (which we never > used in the past), the order was wrong, so QEMU complains with a > "Incorrect order for descriptors" message as soon as we use it for > SCSI WRITE commands. > > Signed-off-by: Thomas Huth <thuth@redhat.com> Thanks, applied. > --- > lib/libvirtio/virtio-scsi.c | 19 ++++++++++++++----- > 1 file changed, 14 insertions(+), 5 deletions(-) > > diff --git a/lib/libvirtio/virtio-scsi.c b/lib/libvirtio/virtio-scsi.c > index 04181b0..36b62d1 100644 > --- a/lib/libvirtio/virtio-scsi.c > +++ b/lib/libvirtio/virtio-scsi.c > @@ -49,18 +49,27 @@ int virtioscsi_send(struct virtio_device *dev, > virtio_fill_desc(&vq_desc[id], dev->is_modern, (uint64_t)req, sizeof(*req), VRING_DESC_F_NEXT, > (id + 1) % vq_size); > > - /* Set up virtqueue descriptor for data */ > - if (buf && buf_len) { > + if (buf == NULL || buf_len == 0) { > + /* Set up descriptor for response information */ > + virtio_fill_desc(&vq_desc[(id + 1) % vq_size], dev->is_modern, > + (uint64_t)resp, sizeof(*resp), > + VRING_DESC_F_WRITE, 0); > + } else if (is_read) { > + /* Set up descriptor for response information */ > virtio_fill_desc(&vq_desc[(id + 1) % vq_size], dev->is_modern, > (uint64_t)resp, sizeof(*resp), > VRING_DESC_F_NEXT | VRING_DESC_F_WRITE, > (id + 2) % vq_size); > - /* Set up virtqueue descriptor for status */ > + /* Set up virtqueue descriptor for data from device */ > virtio_fill_desc(&vq_desc[(id + 2) % vq_size], dev->is_modern, > - (uint64_t)buf, buf_len, > - (is_read ? VRING_DESC_F_WRITE : 0), 0); > + (uint64_t)buf, buf_len, VRING_DESC_F_WRITE, 0); > } else { > + /* Set up virtqueue descriptor for data to device */ > virtio_fill_desc(&vq_desc[(id + 1) % vq_size], dev->is_modern, > + (uint64_t)buf, buf_len, VRING_DESC_F_NEXT, > + (id + 2) % vq_size); > + /* Set up descriptor for response information */ > + virtio_fill_desc(&vq_desc[(id + 2) % vq_size], dev->is_modern, > (uint64_t)resp, sizeof(*resp), > VRING_DESC_F_WRITE, 0); > } >
diff --git a/lib/libvirtio/virtio-scsi.c b/lib/libvirtio/virtio-scsi.c index 04181b0..36b62d1 100644 --- a/lib/libvirtio/virtio-scsi.c +++ b/lib/libvirtio/virtio-scsi.c @@ -49,18 +49,27 @@ int virtioscsi_send(struct virtio_device *dev, virtio_fill_desc(&vq_desc[id], dev->is_modern, (uint64_t)req, sizeof(*req), VRING_DESC_F_NEXT, (id + 1) % vq_size); - /* Set up virtqueue descriptor for data */ - if (buf && buf_len) { + if (buf == NULL || buf_len == 0) { + /* Set up descriptor for response information */ + virtio_fill_desc(&vq_desc[(id + 1) % vq_size], dev->is_modern, + (uint64_t)resp, sizeof(*resp), + VRING_DESC_F_WRITE, 0); + } else if (is_read) { + /* Set up descriptor for response information */ virtio_fill_desc(&vq_desc[(id + 1) % vq_size], dev->is_modern, (uint64_t)resp, sizeof(*resp), VRING_DESC_F_NEXT | VRING_DESC_F_WRITE, (id + 2) % vq_size); - /* Set up virtqueue descriptor for status */ + /* Set up virtqueue descriptor for data from device */ virtio_fill_desc(&vq_desc[(id + 2) % vq_size], dev->is_modern, - (uint64_t)buf, buf_len, - (is_read ? VRING_DESC_F_WRITE : 0), 0); + (uint64_t)buf, buf_len, VRING_DESC_F_WRITE, 0); } else { + /* Set up virtqueue descriptor for data to device */ virtio_fill_desc(&vq_desc[(id + 1) % vq_size], dev->is_modern, + (uint64_t)buf, buf_len, VRING_DESC_F_NEXT, + (id + 2) % vq_size); + /* Set up descriptor for response information */ + virtio_fill_desc(&vq_desc[(id + 2) % vq_size], dev->is_modern, (uint64_t)resp, sizeof(*resp), VRING_DESC_F_WRITE, 0); }
Virtio needs the descriptors ordered: All descriptors for buffers that contain data that should go *to* the device have to be put into the queue first. The descriptors for buffers that read *from* the device have to be sorted in last. For SCSI WRITE commands (which we never used in the past), the order was wrong, so QEMU complains with a "Incorrect order for descriptors" message as soon as we use it for SCSI WRITE commands. Signed-off-by: Thomas Huth <thuth@redhat.com> --- lib/libvirtio/virtio-scsi.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)