From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52435) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZrkSK-0004Fh-5x for qemu-devel@nongnu.org; Thu, 29 Oct 2015 06:29:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZrkSJ-0005WZ-7Y for qemu-devel@nongnu.org; Thu, 29 Oct 2015 06:29:16 -0400 Date: Thu, 29 Oct 2015 11:29:05 +0100 From: Igor Mammedov Message-ID: <20151029112905.55d9b975@igors-macbook-pro.local> In-Reply-To: <1446047243-3221-1-git-send-email-mst@redhat.com> References: <1446047243-3221-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH 1/2] dataplane: simplify indirect descriptor read List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Michael S. Tsirkin" Cc: Stefan Hajnoczi , qemu-devel@nongnu.org, qemu-block@nongnu.org On Wed, 28 Oct 2015 17:48:02 +0200 "Michael S. Tsirkin" wrote: > Use address_space_read to make sure we handle the case of an indirect > descriptor crossing DIMM boundary correctly. > > Signed-off-by: Michael S. Tsirkin Tested-by: Igor Mammedov > --- > > Warning: compile-tested only. > > hw/virtio/dataplane/vring.c | 28 ++++++++++++++++++---------- > 1 file changed, 18 insertions(+), 10 deletions(-) > > diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c > index 68f1994..0b92fcf 100644 > --- a/hw/virtio/dataplane/vring.c > +++ b/hw/virtio/dataplane/vring.c > @@ -257,6 +257,21 @@ static void copy_in_vring_desc(VirtIODevice > *vdev, host->next = virtio_lduw_p(vdev, &guest->next); > } > > +static bool read_vring_desc(VirtIODevice *vdev, > + hwaddr guest, > + struct vring_desc *host) > +{ > + if (address_space_read(&address_space_memory, guest, > MEMTXATTRS_UNSPECIFIED, > + (uint8_t *)host, sizeof *host)) { > + return false; > + } > + host->addr = virtio_tswap64(vdev, host->addr); > + host->len = virtio_tswap32(vdev, host->len); > + host->flags = virtio_tswap16(vdev, host->flags); > + host->next = virtio_tswap16(vdev, host->next); > + return true; > +} > + > /* This is stolen from linux/drivers/vhost/vhost.c. */ > static int get_indirect(VirtIODevice *vdev, Vring *vring, > VirtQueueElement *elem, struct vring_desc > *indirect) @@ -284,23 +299,16 @@ static int get_indirect(VirtIODevice > *vdev, Vring *vring, } > > do { > - struct vring_desc *desc_ptr; > - MemoryRegion *mr; > - > /* Translate indirect descriptor */ > - desc_ptr = vring_map(&mr, > - indirect->addr + found * sizeof(desc), > - sizeof(desc), false); > - if (!desc_ptr) { > - error_report("Failed to map indirect descriptor " > + if (!read_vring_desc(vdev, indirect->addr + found * > sizeof(desc), > + &desc)) { > + error_report("Failed to read indirect descriptor " > "addr %#" PRIx64 " len %zu", > (uint64_t)indirect->addr + found * > sizeof(desc), sizeof(desc)); > vring->broken = true; > return -EFAULT; > } > - copy_in_vring_desc(vdev, desc_ptr, &desc); > - memory_region_unref(mr); > > /* Ensure descriptor has been loaded before accessing fields > */ barrier(); /* read_barrier_depends(); */