qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 05/40] virtio: read/write the VirtQueueElement a


From: Fam Zheng
Subject: Re: [Qemu-devel] [PATCH 05/40] virtio: read/write the VirtQueueElement a field at a time
Date: Mon, 30 Nov 2015 17:47:21 +0800
User-agent: Mutt/1.5.21 (2010-09-15)

On Tue, 11/24 19:00, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini <address@hidden>
> ---
>  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
> 
> 
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]