From patchwork Tue Oct 6 19:19:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 526998 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 785A6140D96 for ; Wed, 7 Oct 2015 08:12:32 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=IKBNJ91Y; dkim-atps=neutral Received: from localhost ([::1]:54079 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZjZXC-0006VN-FV for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2015 17:12:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42793) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZjZVy-00057n-H2 for qemu-devel@nongnu.org; Tue, 06 Oct 2015 17:11:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZjZVv-0008AB-Ca for qemu-devel@nongnu.org; Tue, 06 Oct 2015 17:11:14 -0400 Received: from mail-qg0-x234.google.com ([2607:f8b0:400d:c04::234]:33814) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZjXok-0008OY-PV for qemu-devel@nongnu.org; Tue, 06 Oct 2015 15:22:31 -0400 Received: by qgez77 with SMTP id z77so184277071qge.1 for ; Tue, 06 Oct 2015 12:22:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=1xFSFfOfBnTl8PDLaDY/Nh1g16TTi1ZUZ328KQQK/do=; b=IKBNJ91Y+e7FxEfgsApoPiDKgqRbcZGIefiqg9p60p+p2O8zwtXfk57DclGLZKUbFc sdiorl/pvirB7hz0BpfBGpZhqqvMWB5vlxUFnsmOODU2bS/3/6xyLdqqilmhyfOwhE36 KYoQHL+LZZmJv7IV60+/7ziM30MyyJnIYc5szmMYqAQQgDSdvMjETCYSW3hXPquhTX2F qXKKlPm0lQl85rLgBnLS132zuXLhhIZrLd6+axADKUVLugZHpHVI8t+pLU5JAg0cNBvy YmPTuaEB0rSFLHMXl2z5fdnKi0Et4E0Hjpzhi0CkpmC9DX0CwvZPe8D8mB4K6STgXBRH /QNQ== X-Received: by 10.140.194.8 with SMTP id p8mr52403746qha.63.1444159350253; Tue, 06 Oct 2015 12:22:30 -0700 (PDT) Received: from localhost (bne75-h02-31-39-163-232.dsl.sta.abo.bbox.fr. [31.39.163.232]) by smtp.gmail.com with ESMTPSA id 206sm14420720qhq.39.2015.10.06.12.22.29 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Oct 2015 12:22:29 -0700 (PDT) From: marcandre.lureau@redhat.com To: peter.maydell@linaro.org Date: Tue, 6 Oct 2015 21:19:44 +0200 Message-Id: <1444159184-18153-49-git-send-email-marcandre.lureau@redhat.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1444159184-18153-1-git-send-email-marcandre.lureau@redhat.com> References: <1444159184-18153-1-git-send-email-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400d:c04::234 Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , qemu-devel@nongnu.org Subject: [Qemu-devel] [PULL 48/48] ivshmem: use little-endian int64_t for the protocol X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Marc-André Lureau 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 Reviewed-by: Claudio Fontana --- contrib/ivshmem-client/ivshmem-client.c | 11 ++++++----- contrib/ivshmem-client/ivshmem-client.h | 4 ++-- contrib/ivshmem-server/ivshmem-server.c | 5 +++-- contrib/ivshmem-server/ivshmem-server.h | 4 ++-- docs/specs/ivshmem_device_spec.txt | 2 +- hw/misc/ivshmem.c | 29 +++++++++++++++++++---------- 6 files changed, 33 insertions(+), 22 deletions(-) diff --git a/contrib/ivshmem-client/ivshmem-client.c b/contrib/ivshmem-client/ivshmem-client.c index 33dc529..d628d11 100644 --- a/contrib/ivshmem-client/ivshmem-client.c +++ b/contrib/ivshmem-client/ivshmem-client.c @@ -24,7 +24,7 @@ /* read message from the unix socket */ static int -ivshmem_client_read_one_msg(IvshmemClient *client, long *index, int *fd) +ivshmem_client_read_one_msg(IvshmemClient *client, int64_t *index, int *fd) { int ret; struct msghdr msg; @@ -45,7 +45,7 @@ ivshmem_client_read_one_msg(IvshmemClient *client, long *index, int *fd) msg.msg_controllen = sizeof(msg_control); ret = recvmsg(client->sock_fd, &msg, 0); - if (ret < 0) { + if (ret < sizeof(*index)) { IVSHMEM_CLIENT_DEBUG(client, "cannot read message: %s\n", strerror(errno)); return -1; @@ -55,6 +55,7 @@ ivshmem_client_read_one_msg(IvshmemClient *client, long *index, int *fd) return -1; } + *index = GINT64_FROM_LE(*index); *fd = -1; for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { @@ -91,7 +92,7 @@ static int ivshmem_client_handle_server_msg(IvshmemClient *client) { IvshmemClientPeer *peer; - long peer_id; + int64_t peer_id; int ret, fd; ret = ivshmem_client_read_one_msg(client, &peer_id, &fd); @@ -180,7 +181,7 @@ ivshmem_client_connect(IvshmemClient *client) { struct sockaddr_un sun; int fd, ret; - long tmp; + int64_t tmp; IVSHMEM_CLIENT_DEBUG(client, "connect to client %s\n", client->unix_sock_path); @@ -402,7 +403,7 @@ ivshmem_client_notify_broadcast(const IvshmemClient *client) /* lookup peer from its id */ IvshmemClientPeer * -ivshmem_client_search_peer(IvshmemClient *client, long peer_id) +ivshmem_client_search_peer(IvshmemClient *client, int64_t peer_id) { IvshmemClientPeer *peer; diff --git a/contrib/ivshmem-client/ivshmem-client.h b/contrib/ivshmem-client/ivshmem-client.h index 9215f34..3a4f809 100644 --- a/contrib/ivshmem-client/ivshmem-client.h +++ b/contrib/ivshmem-client/ivshmem-client.h @@ -43,7 +43,7 @@ */ typedef struct IvshmemClientPeer { QTAILQ_ENTRY(IvshmemClientPeer) next; /**< next in list*/ - long id; /**< the id of the peer */ + int64_t id; /**< the id of the peer */ int vectors[IVSHMEM_CLIENT_MAX_VECTORS]; /**< one fd per vector */ unsigned vectors_count; /**< number of vectors */ } IvshmemClientPeer; @@ -198,7 +198,7 @@ int ivshmem_client_notify_broadcast(const IvshmemClient *client); * Returns: The peer structure, or NULL if not found */ IvshmemClientPeer * -ivshmem_client_search_peer(IvshmemClient *client, long peer_id); +ivshmem_client_search_peer(IvshmemClient *client, int64_t peer_id); /** * Dump information of this ivshmem client on stdout diff --git a/contrib/ivshmem-server/ivshmem-server.c b/contrib/ivshmem-server/ivshmem-server.c index 060f414..3742a78 100644 --- a/contrib/ivshmem-server/ivshmem-server.c +++ b/contrib/ivshmem-server/ivshmem-server.c @@ -33,7 +33,7 @@ /* send message to a client unix socket */ static int -ivshmem_server_send_one_msg(int sock_fd, long peer_id, int fd) +ivshmem_server_send_one_msg(int sock_fd, int64_t peer_id, int fd) { int ret; struct msghdr msg; @@ -44,6 +44,7 @@ ivshmem_server_send_one_msg(int sock_fd, long peer_id, int fd) } msg_control; struct cmsghdr *cmsg; + peer_id = GINT64_TO_LE(peer_id); iov[0].iov_base = &peer_id; iov[0].iov_len = sizeof(peer_id); @@ -448,7 +449,7 @@ ivshmem_server_handle_fds(IvshmemServer *server, fd_set *fds, int maxfd) /* lookup peer from its id */ IvshmemServerPeer * -ivshmem_server_search_peer(IvshmemServer *server, long peer_id) +ivshmem_server_search_peer(IvshmemServer *server, int64_t peer_id) { IvshmemServerPeer *peer; diff --git a/contrib/ivshmem-server/ivshmem-server.h b/contrib/ivshmem-server/ivshmem-server.h index 65b3c2d..d179f22 100644 --- a/contrib/ivshmem-server/ivshmem-server.h +++ b/contrib/ivshmem-server/ivshmem-server.h @@ -50,7 +50,7 @@ typedef struct IvshmemServerPeer { QTAILQ_ENTRY(IvshmemServerPeer) next; /**< next in list*/ int sock_fd; /**< connected unix sock */ - long id; /**< the id of the peer */ + int64_t id; /**< the id of the peer */ int vectors[IVSHMEM_SERVER_MAX_VECTORS]; /**< one fd per vector */ unsigned vectors_count; /**< number of vectors */ } IvshmemServerPeer; @@ -154,7 +154,7 @@ int ivshmem_server_handle_fds(IvshmemServer *server, fd_set *fds, int maxfd); * Returns: The peer structure, or NULL if not found */ IvshmemServerPeer * -ivshmem_server_search_peer(IvshmemServer *server, long peer_id); +ivshmem_server_search_peer(IvshmemServer *server, int64_t peer_id); /** * Dump information of this ivshmem server and its peers on stdout diff --git a/docs/specs/ivshmem_device_spec.txt b/docs/specs/ivshmem_device_spec.txt index 3435116..d318d65 100644 --- a/docs/specs/ivshmem_device_spec.txt +++ b/docs/specs/ivshmem_device_spec.txt @@ -61,7 +61,7 @@ This server code is available in qemu.git/contrib/ivshmem-server. The server must be started on the host before any guest. It creates a shared memory object then waits for clients to connect on a unix -socket. +socket. All the messages are little-endian int64_t integer. For each client (QEMU process) that connects to the server: - the server sends a protocol version, if client does not support it, the client diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index 7c7c80d..227a4db 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,12 +614,11 @@ 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; } @@ -716,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; } @@ -874,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) &&