From patchwork Tue Feb 4 16:53:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Deacon X-Patchwork-Id: 3578071 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 93F6B9F383 for ; Tue, 4 Feb 2014 16:55:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BC9DD201B4 for ; Tue, 4 Feb 2014 16:55:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E375E20181 for ; Tue, 4 Feb 2014 16:55:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932302AbaBDQyr (ORCPT ); Tue, 4 Feb 2014 11:54:47 -0500 Received: from cam-admin0.cambridge.arm.com ([217.140.96.50]:49670 "EHLO cam-admin0.cambridge.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932249AbaBDQyb (ORCPT ); Tue, 4 Feb 2014 11:54:31 -0500 Received: from mudshark.cambridge.arm.com (mudshark.cambridge.arm.com [10.1.203.36]) by cam-admin0.cambridge.arm.com (8.12.6/8.12.6) with ESMTP id s14Gs9ki003406; Tue, 4 Feb 2014 16:54:09 GMT Received: by mudshark.cambridge.arm.com (Postfix, from userid 1000) id 7230CC2A8A; Tue, 4 Feb 2014 16:54:08 +0000 (GMT) From: Will Deacon To: kvm@vger.kernel.org Cc: kvmarm@lists.cs.columbia.edu, penberg@kernel.org, marc.zyngier@arm.com, arnd@arndb.de, Will Deacon Subject: [PATCH 03/17] kvm tools: net: don't propagate error codes from tx/rx operations Date: Tue, 4 Feb 2014 16:53:51 +0000 Message-Id: <1391532845-2177-4-git-send-email-will.deacon@arm.com> X-Mailer: git-send-email 1.8.2.2 In-Reply-To: <1391532845-2177-1-git-send-email-will.deacon@arm.com> References: <1391532845-2177-1-git-send-email-will.deacon@arm.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently, if a ->tx or ->rx callback into the net_dev_operations encounters an error, it returns -1 to the virtio-net code, which in turn treats this as an unsigned (size_t) size describing the data available. The resulting memcpy operation then quickly explodes with a SEGV. This patch detects the error code from the low-level callbacks and exits the thread dealing with the erroneous queue. Signed-off-by: Will Deacon --- tools/kvm/net/uip/core.c | 2 +- tools/kvm/virtio/net.c | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tools/kvm/net/uip/core.c b/tools/kvm/net/uip/core.c index b3cd8c25d4da..e860f3afec97 100644 --- a/tools/kvm/net/uip/core.c +++ b/tools/kvm/net/uip/core.c @@ -36,7 +36,7 @@ int uip_tx(struct iovec *iov, u16 out, struct uip_info *info) buf = malloc(eth_len); if (!buf) - return -1; + return -ENOMEM; eth = (struct uip_eth *)buf; for (i = 1; i < out; i++) { diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c index 2f61718a5029..ae4712c3c550 100644 --- a/tools/kvm/virtio/net.c +++ b/tools/kvm/virtio/net.c @@ -81,7 +81,7 @@ static void *virtio_net_rx_thread(void *p) struct net_dev *ndev = p; u16 out, in; u16 head; - size_t len, copied; + int len, copied; u32 id; mutex_lock(&ndev->mutex); @@ -108,11 +108,17 @@ static void *virtio_net_rx_thread(void *p) struct virtio_net_hdr_mrg_rxbuf *hdr; len = ndev->ops->rx(&dummy_iov, 1, ndev); + if (len < 0) { + pr_warning("%s: rx on vq %u failed (%d), exiting thread\n", + __func__, id, len); + goto out_err; + } + copied = 0; head = virt_queue__get_iov(vq, iov, &out, &in, kvm); hdr = (void *)iov[0].iov_base; while (copied < len) { - size_t iovsize = min(len - copied, iov_size(iov, in)); + size_t iovsize = min_t(size_t, len - copied, iov_size(iov, in)); memcpy_toiovec(iov, buffer + copied, iovsize); copied += iovsize; @@ -131,6 +137,7 @@ static void *virtio_net_rx_thread(void *p) } } +out_err: pthread_exit(NULL); return NULL; @@ -165,6 +172,12 @@ static void *virtio_net_tx_thread(void *p) while (virt_queue__available(vq)) { head = virt_queue__get_iov(vq, iov, &out, &in, kvm); len = ndev->ops->tx(iov, out, ndev); + if (len < 0) { + pr_warning("%s: tx on vq %u failed (%d)\n", + __func__, id, len); + goto out_err; + } + virt_queue__set_used_elem(vq, head, len); } @@ -172,10 +185,9 @@ static void *virtio_net_tx_thread(void *p) ndev->vdev.ops->signal_vq(kvm, &ndev->vdev, id); } +out_err: pthread_exit(NULL); - return NULL; - } static virtio_net_ctrl_ack virtio_net_handle_mq(struct kvm* kvm, struct net_dev *ndev, struct virtio_net_ctrl_hdr *ctrl)