From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34868) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a3L3R-0000UA-Ls for qemu-devel@nongnu.org; Mon, 30 Nov 2015 04:47:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a3L3Q-0005sx-HT for qemu-devel@nongnu.org; Mon, 30 Nov 2015 04:47:29 -0500 Date: Mon, 30 Nov 2015 17:47:21 +0800 From: Fam Zheng Message-ID: <20151130094721.GB5038@ad.usersys.redhat.com> References: <1448388091-117282-1-git-send-email-pbonzini@redhat.com> <1448388091-117282-6-git-send-email-pbonzini@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1448388091-117282-6-git-send-email-pbonzini@redhat.com> Subject: Re: [Qemu-devel] [PATCH 05/40] virtio: read/write the VirtQueueElement a field at a time List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini Cc: qemu-devel@nongnu.org, qemu-block@nongnu.org On Tue, 11/24 19:00, Paolo Bonzini wrote: > Signed-off-by: Paolo Bonzini > --- > hw/virtio/virtio.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 93 insertions(+), 2 deletions(-) > > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c > index fd63206..f5f8108 100644 > --- a/hw/virtio/virtio.c > +++ b/hw/virtio/virtio.c > @@ -578,14 +578,105 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz) > void *qemu_get_virtqueue_element(QEMUFile *f, size_t sz) > { > VirtQueueElement *elem = g_malloc(sz); > - qemu_get_buffer(f, (uint8_t *)elem, sizeof(VirtQueueElement)); > + bool swap; > + hwaddr addr[VIRTQUEUE_MAX_SIZE]; > + struct iovec iov[VIRTQUEUE_MAX_SIZE]; > + uint64_t scratch; > + int i; > + > + qemu_get_be32s(f, &elem->index); > + qemu_get_be32s(f, &elem->out_num); > + qemu_get_be32s(f, &elem->in_num); > + > + swap = (elem->out_num & 0xFFFF0000) || (elem->in_num & 0xFFFF0000); This is interesting, out_num and in_num are 32 bit numbers but there max values are both VIRTQUEUE_MAX_SIZE (thanks for explaining this on IRC), so it can be a clue for the source using a different endianness. Probably worth a few comments here? It's a great patch! Thanks! Fam > + if (swap) { > + bswap32s(&elem->index); > + bswap32s(&elem->out_num); > + bswap32s(&elem->in_num); > + } > + > + for (i = 0; i < elem->in_num; i++) { > + qemu_get_be64s(f, &elem->in_addr[i]); > + if (swap) { > + bswap64s(&elem->in_addr[i]); > + } > + } > + if (i < ARRAY_SIZE(addr)) { > + qemu_get_buffer(f, (uint8_t *)addr, sizeof(addr) - i * sizeof(addr[0])); > + } > + > + for (i = 0; i < elem->out_num; i++) { > + qemu_get_be64s(f, &elem->out_addr[i]); > + if (swap) { > + bswap64s(&elem->out_addr[i]); > + } > + } > + if (i < ARRAY_SIZE(addr)) { > + qemu_get_buffer(f, (uint8_t *)addr, sizeof(addr) - i * sizeof(addr[0])); > + } > + > + for (i = 0; i < elem->in_num; i++) { > + (void) qemu_get_be64(f); /* base */ > + qemu_get_be64s(f, &scratch); /* length */ > + if (swap) { > + bswap64s(&scratch); > + } > + elem->in_sg[i].iov_len = scratch; > + } > + if (i < ARRAY_SIZE(iov)) { > + qemu_get_buffer(f, (uint8_t *)iov, sizeof(iov) - i * sizeof(iov[0])); > + } > + > + for (i = 0; i < elem->out_num; i++) { > + (void) qemu_get_be64(f); /* base */ > + qemu_get_be64s(f, &scratch); /* length */ > + if (swap) { > + bswap64s(&scratch); > + } > + elem->out_sg[i].iov_len = scratch; > + } > + if (i < ARRAY_SIZE(iov)) { > + qemu_get_buffer(f, (uint8_t *)iov, sizeof(iov) - i * sizeof(iov[0])); > + } > + > virtqueue_map(elem); > return elem; > } > > void qemu_put_virtqueue_element(QEMUFile *f, VirtQueueElement *elem) > { > - qemu_put_buffer(f, (uint8_t *)elem, sizeof(VirtQueueElement)); > + hwaddr addr[VIRTQUEUE_MAX_SIZE]; > + struct iovec iov[VIRTQUEUE_MAX_SIZE]; > + int i; > + > + memset(addr, 0, sizeof(addr)); > + memset(iov, 0, sizeof(iov)); > + > + qemu_put_be32s(f, &elem->index); > + qemu_put_be32s(f, &elem->out_num); > + qemu_put_be32s(f, &elem->in_num); > + > + for (i = 0; i < elem->in_num; i++) { > + qemu_put_be64s(f, &elem->in_addr[i]); > + } > + qemu_put_buffer(f, (uint8_t *)addr, sizeof(addr) - i * sizeof(addr[0])); > + > + for (i = 0; i < elem->out_num; i++) { > + qemu_put_be64s(f, &elem->out_addr[i]); > + } > + qemu_put_buffer(f, (uint8_t *)addr, sizeof(addr) - i * sizeof(addr[0])); > + > + for (i = 0; i < elem->in_num; i++) { > + qemu_put_be64(f, 0); > + qemu_put_be64(f, elem->in_sg[i].iov_len); > + } > + qemu_put_buffer(f, (uint8_t *)iov, sizeof(iov) - i * sizeof(iov[0])); > + > + for (i = 0; i < elem->out_num; i++) { > + qemu_put_be64(f, 0); > + qemu_put_be64(f, elem->out_sg[i].iov_len); > + } > + qemu_put_buffer(f, (uint8_t *)iov, sizeof(iov) - i * sizeof(iov[0])); > } > > /* virtio device */ > -- > 1.8.3.1 > > >