From patchwork Thu Jun 30 08:41:11 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Asias He X-Patchwork-Id: 932362 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p5U8jXu9016472 for ; Thu, 30 Jun 2011 08:45:33 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758917Ab1F3Ip3 (ORCPT ); Thu, 30 Jun 2011 04:45:29 -0400 Received: from mail-iy0-f174.google.com ([209.85.210.174]:44108 "EHLO mail-iy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757363Ab1F3Ip2 (ORCPT ); Thu, 30 Jun 2011 04:45:28 -0400 Received: by mail-iy0-f174.google.com with SMTP id 12so1722680iyb.19 for ; Thu, 30 Jun 2011 01:45:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=N+8oURDPQWWzIkdtp7hrKfCW9wGr00hzaXGK1xJef3o=; b=wdizpkFRe6wi748olS9bXYeTLAntJG4KV8cxa/H0XTA7Rs6HNT0tIpdncTd3To5PO7 iaZEntYB+72ScDNHmcpurMF4zEEeuVqqn22WX2Q7mYuF5IadDCd7YvqGj3wX7bELBDI4 bzrdE3qIt2wgcROXpKE08gM+Ji9fQAr2pIWwA= Received: by 10.42.223.198 with SMTP id il6mr1865629icb.271.1309423528479; Thu, 30 Jun 2011 01:45:28 -0700 (PDT) Received: from localhost.localdomain ([219.224.169.130]) by mx.google.com with ESMTPS id d6sm1967338icx.1.2011.06.30.01.45.24 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 30 Jun 2011 01:45:27 -0700 (PDT) From: Asias He To: Pekka Enberg Cc: Cyrill Gorcunov , Ingo Molnar , Sasha Levin , Prasad Joshi , kvm@vger.kernel.org, Asias He Subject: [PATCH v2 23/31] kvm tools: Introduce uip_rx() for uip Date: Thu, 30 Jun 2011 16:41:11 +0800 Message-Id: <1309423279-3093-24-git-send-email-asias.hejun@gmail.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1309423279-3093-1-git-send-email-asias.hejun@gmail.com> References: <1309423279-3093-1-git-send-email-asias.hejun@gmail.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 30 Jun 2011 08:45:33 +0000 (UTC) This patch implement rx interface for uip. uip_rx() can be called in virtio_net_rx_thread(). It is a consumer of the ethernet used buffer. It sleeps until there is used buffer avaiable and copy ethernet data into virtio iov buffers which provided by virtio_net_rx_thread(). Signed-off-by: Asias He --- tools/kvm/include/kvm/uip.h | 1 + tools/kvm/uip/core.c | 61 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 0 deletions(-) diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h index 38ad386..18849d2 100644 --- a/tools/kvm/include/kvm/uip.h +++ b/tools/kvm/include/kvm/uip.h @@ -269,6 +269,7 @@ static inline u16 uip_eth_hdrlen(struct uip_eth *eth) } int uip_tx(struct iovec *iov, u16 out, struct uip_info *info); +int uip_rx(struct iovec *iov, u16 in, struct uip_info *info); int uip_init(struct uip_info *info); int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg); diff --git a/tools/kvm/uip/core.c b/tools/kvm/uip/core.c index 3a37546..7a4b824 100644 --- a/tools/kvm/uip/core.c +++ b/tools/kvm/uip/core.c @@ -74,6 +74,67 @@ int uip_tx(struct iovec *iov, u16 out, struct uip_info *info) return vnet_len + eth_len; } +int uip_rx(struct iovec *iov, u16 in, struct uip_info *info) +{ + struct virtio_net_hdr *vnet; + struct uip_eth *eth; + struct uip_buf *buf; + int vnet_len; + int eth_len; + char *p; + int len; + int cnt; + int i; + + /* + * Sleep until there is a buffer for guest + */ + buf = uip_buf_get_used(info); + + /* + * Fill device to guest buffer, vnet hdr fisrt + */ + vnet_len = iov[0].iov_len; + vnet = iov[0].iov_base; + if (buf->vnet_len > vnet_len) { + len = -1; + goto out; + } + memcpy(vnet, buf->vnet, buf->vnet_len); + + /* + * Then, the real eth data + * Note: Be sure buf->eth_len is not bigger than the buffer len that guest provides + */ + cnt = buf->eth_len; + p = buf->eth; + for (i = 1; i < in; i++) { + eth_len = iov[i].iov_len; + eth = iov[i].iov_base; + if (cnt > eth_len) { + memcpy(eth, p, eth_len); + cnt -= eth_len; + p += eth_len; + } else { + memcpy(eth, p, cnt); + cnt -= cnt; + break; + } + } + + if (cnt) { + pr_warning("uip_rx error"); + len = -1; + goto out; + } + + len = buf->vnet_len + buf->eth_len; + +out: + uip_buf_set_free(info, buf); + return len; +} + int uip_init(struct uip_info *info) { struct list_head *udp_socket_head;