From patchwork Thu Jan 9 14:59:59 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonios Motakis X-Patchwork-Id: 308852 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 369422C00BB for ; Fri, 10 Jan 2014 02:05:11 +1100 (EST) Received: from localhost ([::1]:52468 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W1HAS-0005FL-VS for incoming@patchwork.ozlabs.org; Thu, 09 Jan 2014 10:05:09 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53881) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W1H6q-0000Ps-FP for qemu-devel@nongnu.org; Thu, 09 Jan 2014 10:01:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W1H6k-0000Nk-FY for qemu-devel@nongnu.org; Thu, 09 Jan 2014 10:01:24 -0500 Received: from mail-wi0-f181.google.com ([209.85.212.181]:43830) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W1H6k-0000Nd-77 for qemu-devel@nongnu.org; Thu, 09 Jan 2014 10:01:18 -0500 Received: by mail-wi0-f181.google.com with SMTP id hq4so3574068wib.14 for ; Thu, 09 Jan 2014 07:01:17 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=uJrkW9XU4LPCqmUxbt9kdh/zgCMauSvg6M97ktr+pjg=; b=m+TVF8nsp5Cspst7xDKxSeSX0dr2+QtC7aNTe5RUmuQwNMaAYYHCZH4y4FZTUkCqp1 GCFD/kW9Too41CACIUT8yTMrY0yUglSKWGlVeKnQNPlHRW8xUq02Ybl6q9Unt8jPdjf0 U7SM4KYYvkfeokLPWQWdlIvwcB8trWTkUC5QfgYn/j40jt0ajYy8joahFS9NPDqi092p VxKVQeIXNZUEZzl4Xha0uRy2PNKq0EAs5ozAjA+p3FanubkUBa3QPkEERxNNAjpzDYWq w+D6lq9lwg9j58zzS6fCOk2CgMLNPGw9EIX58257uRHAeUyHv1dyubDLPHZYqNm9FoMc qQEw== X-Gm-Message-State: ALoCoQnmwGThdkNb+1TOwo1p4++zyRa2vp1QRDn4lqmq965YbGVTbChelqqg7ECjW8aE0+vJgZCO X-Received: by 10.195.12.49 with SMTP id en17mr3349257wjd.20.1389279677427; Thu, 09 Jan 2014 07:01:17 -0800 (PST) Received: from localhost.localdomain (home.tvelocity.eu. [82.67.68.96]) by mx.google.com with ESMTPSA id k10sm1765683wjf.11.2014.01.09.07.01.15 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 09 Jan 2014 07:01:16 -0800 (PST) From: Antonios Motakis To: qemu-devel@nongnu.org, snabb-devel@googlegroups.com Date: Thu, 9 Jan 2014 15:59:59 +0100 Message-Id: <1389279601-1924-6-git-send-email-a.motakis@virtualopensystems.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1389279601-1924-1-git-send-email-a.motakis@virtualopensystems.com> References: <1389279601-1924-1-git-send-email-a.motakis@virtualopensystems.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.85.212.181 Cc: lukego@gmail.com, Antonios Motakis , tech@virtualopensystems.com, n.nikolaev@virtualopensystems.com, "Michael S. Tsirkin" Subject: [Qemu-devel] [PATCH v5 5/7] Add vhost-user calls implementation 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 Each ioctl request of vhost-kernel has a vhost-user message equivalent, which is sent it over the control socket. The general approach is to copy the data from the supplied argument pointer to a designated field in the message. If a file descriptor is to be passed it should be placed also in the fds array for inclusion in the sendmsd control header. VHOST_SET_MEM_TABLE ignores the supplied vhost_memory structure and scans the global ram_list for ram blocks wiht a valid fd field set. This would be set when the -mem-path option with shared=on property is used. Signed-off-by: Antonios Motakis Signed-off-by: Nikolay Nikolaev --- hw/virtio/vhost-backend.c | 134 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 2 deletions(-) diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c index b33d35f..50ea307 100644 --- a/hw/virtio/vhost-backend.c +++ b/hw/virtio/vhost-backend.c @@ -81,8 +81,41 @@ typedef struct VhostUserMsg { /* The version of the protocol we support */ #define VHOST_USER_VERSION (0x1) +static unsigned long int ioctl_to_vhost_user_request[VHOST_USER_MAX] = { + -1, /* VHOST_USER_NONE */ + VHOST_GET_FEATURES, /* VHOST_USER_GET_FEATURES */ + VHOST_SET_FEATURES, /* VHOST_USER_SET_FEATURES */ + VHOST_SET_OWNER, /* VHOST_USER_SET_OWNER */ + VHOST_RESET_OWNER, /* VHOST_USER_RESET_OWNER */ + VHOST_SET_MEM_TABLE, /* VHOST_USER_SET_MEM_TABLE */ + VHOST_SET_LOG_BASE, /* VHOST_USER_SET_LOG_BASE */ + VHOST_SET_LOG_FD, /* VHOST_USER_SET_LOG_FD */ + VHOST_SET_VRING_NUM, /* VHOST_USER_SET_VRING_NUM */ + VHOST_SET_VRING_ADDR, /* VHOST_USER_SET_VRING_ADDR */ + VHOST_SET_VRING_BASE, /* VHOST_USER_SET_VRING_BASE */ + VHOST_GET_VRING_BASE, /* VHOST_USER_GET_VRING_BASE */ + VHOST_SET_VRING_KICK, /* VHOST_USER_SET_VRING_KICK */ + VHOST_SET_VRING_CALL, /* VHOST_USER_SET_VRING_CALL */ + VHOST_SET_VRING_ERR, /* VHOST_USER_SET_VRING_ERR */ + VHOST_NET_SET_BACKEND, /* VHOST_USER_NET_SET_BACKEND */ + -1 /* VHOST_USER_ECHO */ +}; + static int vhost_user_cleanup(struct vhost_dev *dev); +static VhostUserRequest vhost_user_request_translate(unsigned long int request) +{ + VhostUserRequest idx; + + for (idx = 0; idx < VHOST_USER_MAX; idx++) { + if (ioctl_to_vhost_user_request[idx] == request) { + break; + } + } + + return (idx == VHOST_USER_MAX) ? VHOST_USER_NONE : idx; +} + static int vhost_user_recv(int fd, VhostUserMsg *msg) { ssize_t r; @@ -197,7 +230,8 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, { int fd = dev->control; VhostUserMsg msg; - int result = 0; + RAMBlock *block = 0; + int result = 0, need_reply = 0; int fds[VHOST_MEMORY_MAX_NREGIONS]; size_t fd_num = 0; @@ -207,11 +241,78 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, return -1; } - msg.request = VHOST_USER_NONE; + msg.request = vhost_user_request_translate(request); msg.flags = VHOST_USER_VERSION; msg.size = 0; switch (request) { + case VHOST_GET_FEATURES: + case VHOST_GET_VRING_BASE: + need_reply = 1; + break; + + case VHOST_SET_FEATURES: + case VHOST_SET_LOG_BASE: + msg.u64 = *((__u64 *) arg); + msg.size = MEMB_SIZE(VhostUserMsg, u64); + break; + + case VHOST_SET_OWNER: + case VHOST_RESET_OWNER: + break; + + case VHOST_SET_MEM_TABLE: + QTAILQ_FOREACH(block, &ram_list.blocks, next) + { + if (block->fd > 0) { + msg.memory.regions[fd_num].userspace_addr = (__u64) block->host; + msg.memory.regions[fd_num].memory_size = block->length; + msg.memory.regions[fd_num].guest_phys_addr = block->offset; + fds[fd_num++] = block->fd; + } + } + + msg.memory.nregions = fd_num; + + if (!fd_num) { + error_report("Failed initializing vhost-user memory map\n" + "consider using -mem-path option\n"); + return -1; + } + + msg.size = MEMB_SIZE(VhostUserMemory, nregions); + msg.size += MEMB_SIZE(VhostUserMemory, padding); + msg.size += fd_num*sizeof(VhostUserMemoryRegion); + + break; + + case VHOST_SET_LOG_FD: + msg.fd = *((int *) arg); + msg.size = MEMB_SIZE(VhostUserMsg, fd); + break; + + case VHOST_SET_VRING_NUM: + case VHOST_SET_VRING_BASE: + memcpy(&msg.state, arg, sizeof(struct vhost_vring_state)); + msg.size = MEMB_SIZE(VhostUserMsg, state); + break; + + case VHOST_SET_VRING_ADDR: + memcpy(&msg.addr, arg, sizeof(struct vhost_vring_addr)); + msg.size = MEMB_SIZE(VhostUserMsg, addr); + break; + + case VHOST_SET_VRING_KICK: + case VHOST_SET_VRING_CALL: + case VHOST_SET_VRING_ERR: + case VHOST_NET_SET_BACKEND: + memcpy(&msg.file, arg, sizeof(struct vhost_vring_file)); + msg.size = MEMB_SIZE(VhostUserMsg, file); + if (msg.file.fd > 0) { + fds[0] = msg.file.fd; + fd_num = 1; + } + break; default: error_report("vhost-user trying to send unhandled ioctl\n"); return -1; @@ -220,6 +321,35 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, result = vhost_user_send_fds(fd, &msg, fds, fd_num); + if (!result && need_reply) { + result = vhost_user_recv(fd, &msg); + + if ((msg.flags & VHOST_USER_REPLY_MASK) == 0 || + (msg.flags & VHOST_USER_VERSION_MASK) != VHOST_USER_VERSION) { + error_report("Received bad msg.\n"); + return -1; + } + + if (!result) { + switch (request) { + case VHOST_GET_FEATURES: + if (msg.size != MEMB_SIZE(VhostUserMsg, u64)) { + error_report("Received bad msg.\n"); + return -1; + } + *((__u64 *) arg) = msg.u64; + break; + case VHOST_GET_VRING_BASE: + if (msg.size != MEMB_SIZE(VhostUserMsg, state)) { + error_report("Received bad msg.\n"); + return -1; + } + memcpy(arg, &msg.state, sizeof(struct vhost_vring_state)); + break; + } + } + } + return result; }