From patchwork Fri Jan 17 12:58:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Dyasli X-Patchwork-Id: 11339009 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F0E8114B4 for ; Fri, 17 Jan 2020 13:00:23 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CD29F20728 for ; Fri, 17 Jan 2020 13:00:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="QXluOba2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CD29F20728 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1isRDb-0000f2-5M; Fri, 17 Jan 2020 12:59:19 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1isRDZ-0000eb-Lu for xen-devel@lists.xen.org; Fri, 17 Jan 2020 12:59:17 +0000 X-Inumbo-ID: 1facaef0-3929-11ea-b50e-12813bfff9fa Received: from esa6.hc3370-68.iphmx.com (unknown [216.71.155.175]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 1facaef0-3929-11ea-b50e-12813bfff9fa; Fri, 17 Jan 2020 12:58:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1579265937; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=imzAVPRg8eCVer6WghQ9w5Jf3bFTfGNNdETp9UAPsoY=; b=QXluOba2XExlniyiikqBuhQwgEdqPzHy4pf4loFUSq+0qUkLc5wCUoO3 O4tVqbg4hsaPvXW+Nb8GAG2TbECHy7mK5oy0sIJHoamAn6F6vW53mjhFJ IeGz1r2g10VNHGkQn0M5R7UJAiJb7I/R2s8bVrYsq/cgPifqcBEwLIfLt o=; 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: 9Pu+Dt4AmrdPopz9X+nqR/BgvGLwCGMi4qVLlyuEh3k94OexmfeofNXTntlanbYRuLsYxfZlBT Lrz3S4mzj+puxMJ8Jo8y0SfffVP7bc/scRO23dHBd+HX4rVw+kT+b7tFlF8c35lmDBLBJ1mctn 9EZXkeeJCjvAkP89TdmjIz9xq7qCRFedYIaST8GIAjgqtr6KH2oRrTOJGpO4JtV9OtGaVMwiCK IH/1chH8J4VSQ7BL2hBX6eO3omZmcU4WoyMDnXGfzaGCdmOjnujJAIYi5Amz6ZEpyDylGUShII GIE= X-SBRS: 2.7 X-MesageID: 11502060 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.70,330,1574139600"; d="scan'208";a="11502060" From: Sergey Dyasli To: , , , Date: Fri, 17 Jan 2020 12:58:34 +0000 Message-ID: <20200117125834.14552-5-sergey.dyasli@citrix.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200117125834.14552-1-sergey.dyasli@citrix.com> References: <20200117125834.14552-1-sergey.dyasli@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v2 4/4] xen/netback: fix grant copy across page boundary X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Sergey Dyasli , Wei Liu , Stefano Stabellini , Paul Durrant , George Dunlap , Ross Lagerwall , Alexander Potapenko , Andrey Ryabinin , Boris Ostrovsky , Andrew Morton , Dmitry Vyukov Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" From: Ross Lagerwall When KASAN (or SLUB_DEBUG) is turned on, there is a higher chance that non-power-of-two allocations are not aligned to the next power of 2 of the size. Therefore, handle grant copies that cross page boundaries. Signed-off-by: Ross Lagerwall Signed-off-by: Sergey Dyasli Acked-by: Paul Durrant --- v1 --> v2: - Use sizeof_field(struct sk_buff, cb)) instead of magic number 48 - Slightly update commit message 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 | 60 +++++++++++++++++++++++++------ 2 files changed, 50 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..f8774ede9f0e 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,11 @@ 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) > + sizeof_field(struct sk_buff, cb)); +} + MODULE_LICENSE("Dual BSD/GPL"); MODULE_ALIAS("xen-backend:vif");