From patchwork Fri Jun 6 01:53:28 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fam Zheng X-Patchwork-Id: 356658 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 9C72D1400A6 for ; Fri, 6 Jun 2014 11:57:23 +1000 (EST) Received: from localhost ([::1]:44700 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WsjPF-0004kN-JV for incoming@patchwork.ozlabs.org; Thu, 05 Jun 2014 21:57:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58787) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WsjLi-0005zA-EF for qemu-devel@nongnu.org; Thu, 05 Jun 2014 21:53:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WsjLc-00054P-9O for qemu-devel@nongnu.org; Thu, 05 Jun 2014 21:53:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:61445) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WsjLc-00054F-1j for qemu-devel@nongnu.org; Thu, 05 Jun 2014 21:53:36 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s561rZfm019693 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 5 Jun 2014 21:53:35 -0400 Received: from T430.nay.redhat.com (dhcp-14-247.nay.redhat.com [10.66.14.247]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s561rEAD002771; Thu, 5 Jun 2014 21:53:34 -0400 From: Fam Zheng To: qemu-devel@nongnu.org Date: Fri, 6 Jun 2014 09:53:28 +0800 Message-Id: <1402019610-2985-8-git-send-email-famz@redhat.com> In-Reply-To: <1402019610-2985-1-git-send-email-famz@redhat.com> References: <1402019610-2985-1-git-send-email-famz@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Kevin Wolf , Paolo Bonzini , Stefan Hajnoczi Subject: [Qemu-devel] [PATCH v3 7/9] virtio-blk: Convert VirtIOBlockReq.out to structrue X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The virtio code currently assumes that the outhdr is in its own iovec. This is not guaranteed by the spec, so we should relax this assumption. Convert the VirtIOBlockReq.out field to structrue so that we can use iov_to_buf and then discard the header from the beginning of iovec. Suggested-by: Paolo Bonzini Signed-off-by: Fam Zheng --- hw/block/virtio-blk.c | 20 ++++++++++++++------ include/hw/virtio/virtio-blk.h | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 388741e..2282e61 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -12,6 +12,7 @@ */ #include "qemu-common.h" +#include "qemu/iov.h" #include "qemu/error-report.h" #include "trace.h" #include "hw/block/block.h" @@ -81,7 +82,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret) trace_virtio_blk_rw_complete(req, ret); if (ret) { - bool is_read = !(ldl_p(&req->out->type) & VIRTIO_BLK_T_OUT); + bool is_read = !(ldl_p(&req->out.type) & VIRTIO_BLK_T_OUT); if (virtio_blk_handle_rw_error(req, -ret, is_read)) return; } @@ -287,7 +288,7 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb) BlockRequest *blkreq; uint64_t sector; - sector = ldq_p(&req->out->sector); + sector = ldq_p(&req->out.sector); bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE); @@ -321,7 +322,7 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req) { uint64_t sector; - sector = ldq_p(&req->out->sector); + sector = ldq_p(&req->out.sector); bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ); @@ -344,22 +345,29 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb) { uint32_t type; + struct iovec *iov = req->elem->out_sg; + unsigned out_num = req->elem->out_num; if (req->elem->out_num < 1 || req->elem->in_num < 1) { error_report("virtio-blk missing headers"); exit(1); } - if (req->elem->out_sg[0].iov_len < sizeof(*req->out) || + if (req->elem->out_sg[0].iov_len < sizeof(req->out) || req->elem->in_sg[req->elem->in_num - 1].iov_len < sizeof(*req->in)) { error_report("virtio-blk header not in correct element"); exit(1); } - req->out = (void *)req->elem->out_sg[0].iov_base; + if (unlikely(iov_to_buf(iov, out_num, 0, &req->out, + sizeof(req->out)) != sizeof(req->out))) { + error_report("virtio-blk request outhdr too short"); + exit(1); + } + iov_discard_front(&iov, &out_num, sizeof(req->out)); req->in = (void *)req->elem->in_sg[req->elem->in_num - 1].iov_base; - type = ldl_p(&req->out->type); + type = ldl_p(&req->out.type); if (type & VIRTIO_BLK_T_FLUSH) { virtio_blk_handle_flush(req, mrb); diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index 1932502..df9b6f9 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -138,7 +138,7 @@ typedef struct VirtIOBlockReq { VirtIOBlock *dev; VirtQueueElement *elem; struct virtio_blk_inhdr *in; - struct virtio_blk_outhdr *out; + struct virtio_blk_outhdr out; QEMUIOVector qiov; struct VirtIOBlockReq *next; BlockAcctCookie acct;