Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp886057ybl; Wed, 8 Jan 2020 07:29:32 -0800 (PST) X-Google-Smtp-Source: APXvYqyIQZSAspP+Ad0h+K2wgixqEPuSVIcrC0AOWWwz1wUMf6TtTb2gsrLHCkIxoyH68TRwIGrC X-Received: by 2002:a05:6830:1615:: with SMTP id g21mr4773765otr.49.1578497372402; Wed, 08 Jan 2020 07:29:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1578497372; cv=none; d=google.com; s=arc-20160816; b=s5GJn/4eFltIAit6tJEYMmLV7WTvSjBcNoG+yhgUPp93QaHgCVVOAJIjLowFBhie5k UwJl4xGJC2AQN2uUhDNkkK5lpwZkUaA9Ho7CaHL2B/aMVYI+Y8sDz5zxJHfxa7UeOPZC cGpfiWbZ5htb+NiRpdYXIphcyPaaDb1I3G8X7RlVX9ENwG7+uS8C5Id2azKWNtSeaw68 HM6GTi1hmxRxxx3ii9IZBWbM9B/iNJM2KZaWUMR8R5htblR23EBjKl6AtmR8iCtj3tR6 DPpuZy+XXn5F4uXqtSD8jOJZEDqElEL+D9ZcEEJb5zfJFJMzCR5mQa6ltdqdpZk3TuGk 4VZw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:ironport-sdr:dkim-signature; bh=NWCg9bQc0zrAeQwS7MlzOnEKTVtDLEnV+SehGUh4Y3U=; b=TyTRj93pKrH6l/ogVvbDMRqX5RaW5k5UWZCxqBNdMo723msr1KvRfnmXQB6otrHr1k XZY+5DYtRnoKDtqKvp9XkxIx6lHHivZRoRNrv79ANYrbFDv+i680ESX/A3Rd7L9eRFgu QbyH1Calvclfmo4A94cBPhNYqF7pp20lr61oSCeyQWLd9NGsy6aSY/L7kcEKghYLC76L FGb6o72T9VAuRV4NLcKEMGOG2NubbYZQECAf1l80FOAez/3fjRh0C6aF4g5+55iXC45M tJYDwBL5SgEgTOhqx5kULRnhOl42b8qBKPPUH1h8CVy9KRJnCCQquAQPALKKTO3P66+c AbQg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@citrix.com header.s=securemail header.b=CvYjTBAD; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=citrix.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l78si1878069oih.182.2020.01.08.07.29.20; Wed, 08 Jan 2020 07:29:32 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@citrix.com header.s=securemail header.b=CvYjTBAD; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=citrix.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728856AbgAHP2Z (ORCPT + 99 others); Wed, 8 Jan 2020 10:28:25 -0500 Received: from esa6.hc3370-68.iphmx.com ([216.71.155.175]:53413 "EHLO esa6.hc3370-68.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728803AbgAHP2X (ORCPT ); Wed, 8 Jan 2020 10:28:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1578497303; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=ndt3rkJJC5cKj6yE6i8y9phmVsBv6Kzxvmo7fe2hCRo=; b=CvYjTBADOSfPbPFZihamnqs2He2s3I77wbQp+yAFyXlKvarcfSpbhVBw XyKEGIF3KzZm8dE5GdsIw1Za0XJVxcZnnJW+hZKRjm29Q3edG4cHdt+vV acNDnhLURXesdxEUT+AJ2mfUBECyfeQ0Ag+2VeJ7A1b2SxXyjrnD/zX+s 8=; Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=sergey.dyasli@citrix.com; spf=Pass smtp.mailfrom=sergey.dyasli@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of sergey.dyasli@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="sergey.dyasli@citrix.com"; x-sender="sergey.dyasli@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa6.hc3370-68.iphmx.com: domain of sergey.dyasli@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="sergey.dyasli@citrix.com"; x-sender="sergey.dyasli@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="sergey.dyasli@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: oiTgJTAJYiU8q6hVq1bN4YDuqH1mfR29MxyRm3RWttoThy1554uFarHZBrmWCz0Qji3LgPyiYl wVYgmEW3+apuNXVHZzQ2evsQ/icA7m0e5gzf3KjRtDbA8Kb81q1Zi+YTZQJT1VeEzKDY9vrqGd mphdiYyxzhMu6ziAdm5TqRpEyDEIa3kEtPXoYBa95UXoue/cu0RlvAuQv+7ixycHCaFCz83l7J 1fF5yzFP14m9eiE+RKg38qcdy3uaCDjVN2GZu5kmbiO046EFaW/01HjVei+dA+4ZV77rJtKOZb ibA= X-SBRS: 2.7 X-MesageID: 11061017 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,410,1571716800"; d="scan'208";a="11061017" From: Sergey Dyasli To: , , , CC: Andrey Ryabinin , Alexander Potapenko , Dmitry Vyukov , Boris Ostrovsky , Juergen Gross , "Stefano Stabellini" , George Dunlap , Ross Lagerwall , Andrew Morton , Sergey Dyasli , Wei Liu , Paul Durrant Subject: [PATCH v1 4/4] xen/netback: Fix grant copy across page boundary with KASAN Date: Wed, 8 Jan 2020 15:21:00 +0000 Message-ID: <20200108152100.7630-5-sergey.dyasli@citrix.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200108152100.7630-1-sergey.dyasli@citrix.com> References: <20200108152100.7630-1-sergey.dyasli@citrix.com> MIME-Version: 1.0 Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ross Lagerwall When KASAN (or SLUB_DEBUG) is turned on, the normal expectation that allocations are aligned to the next power of 2 of the size does not hold. Therefore, handle grant copies that cross page boundaries. Signed-off-by: Ross Lagerwall Signed-off-by: Sergey Dyasli --- RFC --> v1: - Added BUILD_BUG_ON to the netback patch - xenvif_idx_release() now located outside the loop CC: Wei Liu CC: Paul Durrant --- drivers/net/xen-netback/common.h | 2 +- drivers/net/xen-netback/netback.c | 59 +++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 05847eb91a1b..e57684415edd 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h @@ -155,7 +155,7 @@ struct xenvif_queue { /* Per-queue data for xenvif */ struct pending_tx_info pending_tx_info[MAX_PENDING_REQS]; grant_handle_t grant_tx_handle[MAX_PENDING_REQS]; - struct gnttab_copy tx_copy_ops[MAX_PENDING_REQS]; + struct gnttab_copy tx_copy_ops[MAX_PENDING_REQS * 2]; struct gnttab_map_grant_ref tx_map_ops[MAX_PENDING_REQS]; struct gnttab_unmap_grant_ref tx_unmap_ops[MAX_PENDING_REQS]; /* passed to gnttab_[un]map_refs with pages under (un)mapping */ diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 0020b2e8c279..33b8f8d043e6 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -320,6 +320,7 @@ static int xenvif_count_requests(struct xenvif_queue *queue, struct xenvif_tx_cb { u16 pending_idx; + u8 copies; }; #define XENVIF_TX_CB(skb) ((struct xenvif_tx_cb *)(skb)->cb) @@ -439,6 +440,7 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue, { struct gnttab_map_grant_ref *gop_map = *gopp_map; u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx; + u8 copies = XENVIF_TX_CB(skb)->copies; /* This always points to the shinfo of the skb being checked, which * could be either the first or the one on the frag_list */ @@ -450,23 +452,26 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue, int nr_frags = shinfo->nr_frags; const bool sharedslot = nr_frags && frag_get_pending_idx(&shinfo->frags[0]) == pending_idx; - int i, err; + int i, err = 0; - /* Check status of header. */ - err = (*gopp_copy)->status; - if (unlikely(err)) { - if (net_ratelimit()) - netdev_dbg(queue->vif->dev, + while (copies) { + /* Check status of header. */ + int newerr = (*gopp_copy)->status; + if (unlikely(newerr)) { + if (net_ratelimit()) + netdev_dbg(queue->vif->dev, "Grant copy of header failed! status: %d pending_idx: %u ref: %u\n", (*gopp_copy)->status, pending_idx, (*gopp_copy)->source.u.ref); - /* The first frag might still have this slot mapped */ - if (!sharedslot) - xenvif_idx_release(queue, pending_idx, - XEN_NETIF_RSP_ERROR); + err = newerr; + } + (*gopp_copy)++; + copies--; } - (*gopp_copy)++; + /* The first frag might still have this slot mapped */ + if (unlikely(err) && !sharedslot) + xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR); check_frags: for (i = 0; i < nr_frags; i++, gop_map++) { @@ -910,6 +915,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, xenvif_tx_err(queue, &txreq, extra_count, idx); break; } + XENVIF_TX_CB(skb)->copies = 0; skb_shinfo(skb)->nr_frags = ret; if (data_len < txreq.size) @@ -933,6 +939,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, "Can't allocate the frag_list skb.\n"); break; } + XENVIF_TX_CB(nskb)->copies = 0; } if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) { @@ -990,6 +997,31 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue, queue->tx_copy_ops[*copy_ops].len = data_len; queue->tx_copy_ops[*copy_ops].flags = GNTCOPY_source_gref; + XENVIF_TX_CB(skb)->copies++; + + if (offset_in_page(skb->data) + data_len > XEN_PAGE_SIZE) { + unsigned int extra_len = offset_in_page(skb->data) + + data_len - XEN_PAGE_SIZE; + + queue->tx_copy_ops[*copy_ops].len -= extra_len; + (*copy_ops)++; + + queue->tx_copy_ops[*copy_ops].source.u.ref = txreq.gref; + queue->tx_copy_ops[*copy_ops].source.domid = + queue->vif->domid; + queue->tx_copy_ops[*copy_ops].source.offset = + txreq.offset + data_len - extra_len; + + queue->tx_copy_ops[*copy_ops].dest.u.gmfn = + virt_to_gfn(skb->data + data_len - extra_len); + queue->tx_copy_ops[*copy_ops].dest.domid = DOMID_SELF; + queue->tx_copy_ops[*copy_ops].dest.offset = 0; + + queue->tx_copy_ops[*copy_ops].len = extra_len; + queue->tx_copy_ops[*copy_ops].flags = GNTCOPY_source_gref; + + XENVIF_TX_CB(skb)->copies++; + } (*copy_ops)++; @@ -1674,5 +1706,10 @@ static void __exit netback_fini(void) } module_exit(netback_fini); +static void __init __maybe_unused build_assertions(void) +{ + BUILD_BUG_ON(sizeof(struct xenvif_tx_cb) > 48); +} + MODULE_LICENSE("Dual BSD/GPL"); MODULE_ALIAS("xen-backend:vif"); -- 2.17.1