diff options
author | Marc-André Lureau <marcandre.lureau@redhat.com> | 2015-09-24 12:55:01 +0200 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@redhat.com> | 2015-10-26 10:19:53 +0100 |
commit | f7a199b2b4486242271f769bb4bc2638c0413274 (patch) | |
tree | f63f2b1bc536e1064cabbdf12f0c406f85560643 /hw | |
parent | 660c97eef6f8f416c5dc24d3798e29f9f9f698fb (diff) | |
download | qemu-f7a199b2b4486242271f769bb4bc2638c0413274.tar.gz qemu-f7a199b2b4486242271f769bb4bc2638c0413274.tar.bz2 qemu-f7a199b2b4486242271f769bb4bc2638c0413274.zip |
ivshmem: use little-endian int64_t for the protocol
The current ivshmem protocol uses 'long' for integers. But the
sizeof(long) depends on the host and the endianess is not defined, which
may cause portability troubles.
Instead, switch to using little-endian int64_t. This breaks the
protocol, except on x64 little-endian host where this change
should be compatible.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/misc/ivshmem.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index e9dae834da..83d7bd3e5f 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -276,7 +276,7 @@ static void ivshmem_receive(void *opaque, const uint8_t *buf, int size) static int ivshmem_can_receive(void * opaque) { - return sizeof(long); + return sizeof(int64_t); } static void ivshmem_event(void *opaque, int event) @@ -516,7 +516,7 @@ static bool fifo_update_and_get(IVShmemState *s, const uint8_t *buf, int size, const uint8_t *p; uint32_t num; - assert(len <= sizeof(long)); /* limitation of the fifo */ + assert(len <= sizeof(int64_t)); /* limitation of the fifo */ if (fifo8_is_empty(&s->incoming_fifo) && size == len) { memcpy(data, buf, size); return true; @@ -524,7 +524,7 @@ static bool fifo_update_and_get(IVShmemState *s, const uint8_t *buf, int size, IVSHMEM_DPRINTF("short read of %d bytes\n", size); - num = MIN(size, sizeof(long) - fifo8_num_used(&s->incoming_fifo)); + num = MIN(size, sizeof(int64_t) - fifo8_num_used(&s->incoming_fifo)); fifo8_push_all(&s->incoming_fifo, buf, num); if (fifo8_num_used(&s->incoming_fifo) < len) { @@ -546,6 +546,17 @@ static bool fifo_update_and_get(IVShmemState *s, const uint8_t *buf, int size, return true; } +static bool fifo_update_and_get_i64(IVShmemState *s, + const uint8_t *buf, int size, int64_t *i64) +{ + if (fifo_update_and_get(s, buf, size, i64, sizeof(*i64))) { + *i64 = GINT64_FROM_LE(*i64); + return true; + } + + return false; +} + static int ivshmem_add_kvm_msi_virq(IVShmemState *s, int vector) { PCIDevice *pdev = PCI_DEVICE(s); @@ -603,23 +614,23 @@ static void ivshmem_read(void *opaque, const uint8_t *buf, int size) IVShmemState *s = opaque; int incoming_fd; int new_eventfd; - long incoming_posn; + int64_t incoming_posn; Error *err = NULL; Peer *peer; - if (!fifo_update_and_get(s, buf, size, - &incoming_posn, sizeof(incoming_posn))) { + if (!fifo_update_and_get_i64(s, buf, size, &incoming_posn)) { return; } if (incoming_posn < -1) { - IVSHMEM_DPRINTF("invalid incoming_posn %ld\n", incoming_posn); + IVSHMEM_DPRINTF("invalid incoming_posn %" PRId64 "\n", incoming_posn); return; } /* pick off s->server_chr->msgfd and store it, posn should accompany msg */ incoming_fd = qemu_chr_fe_get_msgfd(s->server_chr); - IVSHMEM_DPRINTF("posn is %ld, fd is %d\n", incoming_posn, incoming_fd); + IVSHMEM_DPRINTF("posn is %" PRId64 ", fd is %d\n", + incoming_posn, incoming_fd); /* make sure we have enough space for this peer */ if (incoming_posn >= s->nb_peers) { @@ -641,7 +652,7 @@ static void ivshmem_read(void *opaque, const uint8_t *buf, int size) s->vm_id = incoming_posn; } else { /* otherwise an fd == -1 means an existing peer has gone away */ - IVSHMEM_DPRINTF("posn %ld has gone away\n", incoming_posn); + IVSHMEM_DPRINTF("posn %" PRId64 " has gone away\n", incoming_posn); close_peer_eventfds(s, incoming_posn); } return; @@ -697,7 +708,7 @@ static void ivshmem_read(void *opaque, const uint8_t *buf, int size) new_eventfd = peer->nb_eventfds++; /* this is an eventfd for a particular peer VM */ - IVSHMEM_DPRINTF("eventfds[%ld][%d] = %d\n", incoming_posn, + IVSHMEM_DPRINTF("eventfds[%" PRId64 "][%d] = %d\n", incoming_posn, new_eventfd, incoming_fd); event_notifier_init_fd(&peer->eventfds[new_eventfd], incoming_fd); fcntl_setfl(incoming_fd, O_NONBLOCK); /* msix/irqfd poll non block */ @@ -715,10 +726,9 @@ static void ivshmem_check_version(void *opaque, const uint8_t * buf, int size) { IVShmemState *s = opaque; int tmp; - long version; + int64_t version; - if (!fifo_update_and_get(s, buf, size, - &version, sizeof(version))) { + if (!fifo_update_and_get_i64(s, buf, size, &version)) { return; } @@ -873,7 +883,7 @@ static void pci_ivshmem_realize(PCIDevice *dev, Error **errp) s->ivshmem_size = size; } - fifo8_create(&s->incoming_fifo, sizeof(long)); + fifo8_create(&s->incoming_fifo, sizeof(int64_t)); /* IRQFD requires MSI */ if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD) && |