All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: "Michael S. Tsirkin" <mst@redhat.com>
Cc: famz@redhat.com, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 7/7] virtio-scsi: add support for the any_layout feature
Date: Thu, 12 Jun 2014 15:52:50 +0200	[thread overview]
Message-ID: <5399B0B2.8090101@redhat.com> (raw)
In-Reply-To: <20140612123326.GA23239@redhat.com>

Il 12/06/2014 14:33, Michael S. Tsirkin ha scritto:
> On Thu, Jun 12, 2014 at 02:09:08PM +0200, Paolo Bonzini wrote:
>> Store the request and response headers by value, and let
>> virtio_scsi_parse_req check that there is only one of datain
>> and dataout.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>  hw/scsi/virtio-scsi.c           | 161 ++++++++++++++++++++++------------------
>>  include/hw/i386/pc.h            |   4 +
>>  include/hw/virtio/virtio-scsi.h |   4 +-
>>  3 files changed, 93 insertions(+), 76 deletions(-)
>>
>> diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
>> index 107e9cb..391717d 100644
>> --- a/hw/scsi/virtio-scsi.c
>> +++ b/hw/scsi/virtio-scsi.c
>> @@ -27,21 +27,26 @@ typedef struct VirtIOSCSIReq {
>>      QEMUSGList qsgl;
>>      SCSIRequest *sreq;
>>      size_t resp_size;
>> +    QEMUIOVector resp_iov;
>>      union {
>> -        char                  *buf;
>> -        VirtIOSCSICmdResp     *cmd;
>> -        VirtIOSCSICtrlTMFResp *tmf;
>> -        VirtIOSCSICtrlANResp  *an;
>> -        VirtIOSCSIEvent       *event;
>> +        VirtIOSCSICmdResp     cmd;
>> +        VirtIOSCSICtrlTMFResp tmf;
>> +        VirtIOSCSICtrlANResp  an;
>> +        VirtIOSCSIEvent       event;
>>      } resp;
>>      union {
>> -        char                  *buf;
>> -        VirtIOSCSICmdReq      *cmd;
>> -        VirtIOSCSICtrlTMFReq  *tmf;
>> -        VirtIOSCSICtrlANReq   *an;
>> +        struct {
>> +            VirtIOSCSICmdReq  cmd;
>> +            uint8_t           cdb[];
>> +        } QEMU_PACKED;
>> +        VirtIOSCSICtrlTMFReq  tmf;
>> +        VirtIOSCSICtrlANReq   an;
>>      } req;
>>  } VirtIOSCSIReq;
>>  
>> +QEMU_BUILD_BUG_ON(offsetof(VirtIOSCSIReq, req.cdb) !=
>> +                  offsetof(VirtIOSCSIReq, req.cmd) + sizeof(VirtIOSCSICmdReq));
>> +
>>  static inline int virtio_scsi_get_lun(uint8_t *lun)
>>  {
>>      return ((lun[2] << 8) | lun[3]) & 0x3FFF;
>> @@ -61,17 +66,21 @@ static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun)
>>  static VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq)
>>  {
>>      VirtIOSCSIReq *req;
>> -    req = g_malloc(sizeof(*req));
>> +    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
>> +
>> +    req = g_malloc(sizeof(*req) + vs->cdb_size);
>>  
>>      req->vq = vq;
>>      req->dev = s;
>>      req->sreq = NULL;
>>      qemu_sglist_init(&req->qsgl, DEVICE(s), 8, &address_space_memory);
>> +    qemu_iovec_init(&req->resp_iov, 1);
>>      return req;
>>  }
>>  
>>  static void virtio_scsi_free_req(VirtIOSCSIReq *req)
>>  {
>> +    qemu_iovec_destroy(&req->resp_iov);
>>      qemu_sglist_destroy(&req->qsgl);
>>      g_free(req);
>>  }
>> @@ -81,7 +90,9 @@ static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
>>      VirtIOSCSI *s = req->dev;
>>      VirtQueue *vq = req->vq;
>>      VirtIODevice *vdev = VIRTIO_DEVICE(s);
>> -    virtqueue_push(vq, &req->elem, req->qsgl.size + req->elem.in_sg[0].iov_len);
>> +
>> +    qemu_iovec_from_buf(&req->resp_iov, 0, &req->resp, req->resp_size);
>> +    virtqueue_push(vq, &req->elem, req->qsgl.size + req->resp_iov.size);
>>      if (req->sreq) {
>>          req->sreq->hba_private = NULL;
>>          scsi_req_unref(req->sreq);
>> @@ -122,31 +133,29 @@ static size_t qemu_sgl_concat(VirtIOSCSIReq *req, struct iovec *iov,
>>  static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
>>                                   unsigned req_size, unsigned resp_size)
>>  {
>> -    if (req->elem.in_num == 0) {
>> -        return -EINVAL;
>> -    }
>> +    size_t in_size, out_size;
>>  
>> -    if (req->elem.out_sg[0].iov_len < req_size) {
>> +    if (iov_to_buf(&req->elem.out_sg[0], req->elem.out_num, 0,
>> +                   &req->req, req_size) < req_size) {
>>          return -EINVAL;
>>      }
> 
> I'd like to suggest converting &req->elem.out_sg[0] to
> plain req->elem.out_sg. We can then easily greap for
> in_sg[X] out_sg[X] and take that as a sign that
> any_layout rules are violated.

Very good idea, and it found a place where I was using iov_len instead 
of the iov_size() function.

I also noticed that I'm using in_num > 1 to check for read vs. write 
commands.  All fixed like this:

diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index ddfe5c7..73626fa 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -27,6 +27,7 @@ typedef struct VirtIOSCSIReq {
     QEMUSGList qsgl;
     SCSIRequest *sreq;
     size_t resp_size;
+    enum SCSIXferMode mode;
     QEMUIOVector resp_iov;
     union {
         VirtIOSCSICmdResp     cmd;
         VirtIOSCSICtrlTMFResp tmf;
@@ -158,6 +162,12 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
         return -ENOTSUP;
     }
 
+    if (out_size) {
+        req->mode = SCSI_XFER_TO_DEV;
+    } else if (in_size) {
+        req->mode = SCSI_XFER_FROM_DEV;
+    }
+
     return 0;
 }
 
@@ -213,10 +223,7 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
     scsi_req_ref(sreq);
     req->sreq = sreq;
     if (req->sreq->cmd.mode != SCSI_XFER_NONE) {
-        int req_mode =
-            (req->elem.in_num > 1 ? SCSI_XFER_FROM_DEV : SCSI_XFER_TO_DEV);
-
-        assert(req->sreq->cmd.mode == req_mode);
+        assert(req->sreq->cmd.mode == req->mode);
     }
     return req;
 }
@@ -463,15 +470,11 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
                                  req->req.cdb, req);
 
         if (req->sreq->cmd.mode != SCSI_XFER_NONE) {
-            int req_mode =
-                (req->elem.in_num > 1 ? SCSI_XFER_FROM_DEV : SCSI_XFER_TO_DEV);
-
-            if (req->sreq->cmd.mode != req_mode ||
+            && (req->sreq->cmd.mode != req->mode ||
                 req->sreq->cmd.xfer > req->qsgl.size) {
-                req->resp.cmd.response = VIRTIO_SCSI_S_OVERRUN;
-                virtio_scsi_complete_cmd_req(req);
-                continue;
-            }
+            req->resp.cmd.response = VIRTIO_SCSI_S_OVERRUN;
+            virtio_scsi_complete_cmd_req(req);
+            continue;
         }
 
         n = scsi_req_enqueue(req->sreq);
@@ -575,7 +578,7 @@ static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
         return;
     }
 
-    if (req->elem.out_num || req->elem.in_num != 1) {
+    if (req->elem.out_num) {
         virtio_scsi_bad_req();
     }
 
@@ -584,7 +587,7 @@ static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
         s->events_dropped = false;
     }
 
-    in_size = req->elem.in_sg[0].iov_len;
+    in_size = iov_size(req->elem.in_sg, req->elem.in_num);
     if (in_size < sizeof(VirtIOSCSIEvent)) {
         virtio_scsi_bad_req();
     }

      reply	other threads:[~2014-06-12 13:53 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-12 12:09 [Qemu-devel] [PATCH 0/7] virtio-scsi: do not rely on iov boundaries Paolo Bonzini
2014-06-12 12:09 ` [Qemu-devel] [PATCH 1/7] util: add return value to qemu_iovec_concat_iov Paolo Bonzini
2014-06-12 12:09 ` [Qemu-devel] [PATCH 2/7] virtio-scsi: start preparing for any_layout Paolo Bonzini
2014-06-12 12:09 ` [Qemu-devel] [PATCH 3/7] virtio-scsi: add target swap for VirtIOSCSICtrlTMFReq fields Paolo Bonzini
2014-06-12 12:09 ` [Qemu-devel] [PATCH 4/7] virtio-scsi: add extra argument and return type to qemu_sgl_concat Paolo Bonzini
2014-06-12 12:09 ` [Qemu-devel] [PATCH 5/7] virtio-scsi: prepare sense data handling for any_layout Paolo Bonzini
2014-06-12 12:09 ` [Qemu-devel] [PATCH 6/7] virtio-scsi: introduce virtio_scsi_complete_cmd_req Paolo Bonzini
2014-06-12 12:09 ` [Qemu-devel] [PATCH 7/7] virtio-scsi: add support for the any_layout feature Paolo Bonzini
2014-06-12 12:33   ` Michael S. Tsirkin
2014-06-12 13:52     ` Paolo Bonzini [this message]

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=5399B0B2.8090101@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=famz@redhat.com \
    --cc=mst@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.