[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
>
>
>
- [Qemu-devel] [PATCH 03/40] virtio: move allocation to virtqueue_pop/vring_pop, (continued)
- [Qemu-devel] [PATCH 03/40] virtio: move allocation to virtqueue_pop/vring_pop, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 04/40] virtio: introduce qemu_get/put_virtqueue_element, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 07/40] virtio: slim down allocation of VirtQueueElements, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 08/40] vring: slim down allocation of VirtQueueElements, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 09/40] vring: make vring_enable_notification return void, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 13/40] virtio-blk: fix "disabled data plane" mode, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 05/40] virtio: read/write the VirtQueueElement a field at a time, Paolo Bonzini, 2015/11/24
- Re: [Qemu-devel] [PATCH 05/40] virtio: read/write the VirtQueueElement a field at a time,
Fam Zheng <=
- [Qemu-devel] [PATCH 12/40] virtio: export vring_notify as virtio_should_notify, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 10/40] virtio: combine the read of a descriptor, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 11/40] virtio: add AioContext-specific function for host notifiers, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 14/40] virtio-blk: do not use vring in dataplane, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 15/40] virtio-scsi: do not use vring in dataplane, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 16/40] vring: remove, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 20/40] aio: rename bh_lock to list_lock, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 22/40] aio: make ctx->list_lock a QemuLockCnt, subsuming ctx->walking_bh, Paolo Bonzini, 2015/11/24
- [Qemu-devel] [PATCH 19/40] aio: convert from RFifoLock to QemuRecMutex, Paolo Bonzini, 2015/11/24