From: Sergey Dyasli <sergey.dyasli@citrix.com> To: <xen-devel@lists.xen.org>, <kasan-dev@googlegroups.com>, <linux-mm@kvack.org>, <linux-kernel@vger.kernel.org> Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>, Alexander Potapenko <glider@google.com>, Dmitry Vyukov <dvyukov@google.com>, Boris Ostrovsky <boris.ostrovsky@oracle.com>, Juergen Gross <jgross@suse.com>, "Stefano Stabellini" <sstabellini@kernel.org>, George Dunlap <george.dunlap@citrix.com>, Ross Lagerwall <ross.lagerwall@citrix.com>, Andrew Morton <akpm@linux-foundation.org>, Sergey Dyasli <sergey.dyasli@citrix.com>, Wei Liu <wei.liu@kernel.org>, Paul Durrant <paul@xen.org> Subject: [PATCH v2 4/4] xen/netback: fix grant copy across page boundary Date: Fri, 17 Jan 2020 12:58:34 +0000 [thread overview] Message-ID: <20200117125834.14552-5-sergey.dyasli@citrix.com> (raw) In-Reply-To: <20200117125834.14552-1-sergey.dyasli@citrix.com> From: Ross Lagerwall <ross.lagerwall@citrix.com> 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 <ross.lagerwall@citrix.com> Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com> --- 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 <wei.liu@kernel.org> CC: Paul Durrant <paul@xen.org> --- 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"); -- 2.17.1
WARNING: multiple messages have this Message-ID (diff)
From: Sergey Dyasli <sergey.dyasli@citrix.com> To: <xen-devel@lists.xen.org>, <kasan-dev@googlegroups.com>, <linux-mm@kvack.org>, <linux-kernel@vger.kernel.org> Cc: Juergen Gross <jgross@suse.com>, Sergey Dyasli <sergey.dyasli@citrix.com>, Wei Liu <wei.liu@kernel.org>, Stefano Stabellini <sstabellini@kernel.org>, Paul Durrant <paul@xen.org>, George Dunlap <george.dunlap@citrix.com>, Ross Lagerwall <ross.lagerwall@citrix.com>, Alexander Potapenko <glider@google.com>, Andrey Ryabinin <aryabinin@virtuozzo.com>, Boris Ostrovsky <boris.ostrovsky@oracle.com>, Andrew Morton <akpm@linux-foundation.org>, Dmitry Vyukov <dvyukov@google.com> Subject: [Xen-devel] [PATCH v2 4/4] xen/netback: fix grant copy across page boundary Date: Fri, 17 Jan 2020 12:58:34 +0000 [thread overview] Message-ID: <20200117125834.14552-5-sergey.dyasli@citrix.com> (raw) In-Reply-To: <20200117125834.14552-1-sergey.dyasli@citrix.com> From: Ross Lagerwall <ross.lagerwall@citrix.com> 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 <ross.lagerwall@citrix.com> Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com> --- 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 <wei.liu@kernel.org> CC: Paul Durrant <paul@xen.org> --- 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"); -- 2.17.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2020-01-17 12:59 UTC|newest] Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-01-17 12:58 [PATCH v2 0/4] basic KASAN support for Xen PV domains Sergey Dyasli 2020-01-17 12:58 ` [Xen-devel] " Sergey Dyasli 2020-01-17 12:58 ` [PATCH v2 1/4] kasan: introduce set_pmd_early_shadow() Sergey Dyasli 2020-01-17 12:58 ` [Xen-devel] " Sergey Dyasli 2020-01-17 12:58 ` [PATCH v2 2/4] x86/xen: add basic KASAN support for PV kernel Sergey Dyasli 2020-01-17 12:58 ` [Xen-devel] " Sergey Dyasli 2020-01-17 14:56 ` Boris Ostrovsky 2020-01-17 14:56 ` [Xen-devel] " Boris Ostrovsky 2020-01-22 11:13 ` Sergey Dyasli 2020-01-22 11:13 ` [Xen-devel] " Sergey Dyasli 2020-01-22 11:13 ` Sergey Dyasli 2020-01-21 14:54 ` kbuild test robot 2020-01-21 14:54 ` kbuild test robot 2020-01-21 14:54 ` [Xen-devel] " kbuild test robot 2020-01-21 16:25 ` kbuild test robot 2020-01-21 16:25 ` kbuild test robot 2020-01-21 16:25 ` [Xen-devel] " kbuild test robot 2020-01-17 12:58 ` [PATCH v2 3/4] xen: teach KASAN about grant tables Sergey Dyasli 2020-01-17 12:58 ` [Xen-devel] " Sergey Dyasli 2020-01-17 12:58 ` Sergey Dyasli [this message] 2020-01-17 12:58 ` [Xen-devel] [PATCH v2 4/4] xen/netback: fix grant copy across page boundary Sergey Dyasli 2020-01-20 8:58 ` Paul Durrant 2020-01-20 8:58 ` [Xen-devel] " Paul Durrant 2020-01-20 8:58 ` Paul Durrant 2020-01-22 10:07 ` Sergey Dyasli 2020-01-22 10:07 ` [Xen-devel] " Sergey Dyasli 2020-01-22 10:07 ` Sergey Dyasli 2020-01-22 14:05 ` Wei Liu 2020-01-22 14:05 ` [Xen-devel] " Wei Liu
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200117125834.14552-5-sergey.dyasli@citrix.com \ --to=sergey.dyasli@citrix.com \ --cc=akpm@linux-foundation.org \ --cc=aryabinin@virtuozzo.com \ --cc=boris.ostrovsky@oracle.com \ --cc=dvyukov@google.com \ --cc=george.dunlap@citrix.com \ --cc=glider@google.com \ --cc=jgross@suse.com \ --cc=kasan-dev@googlegroups.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mm@kvack.org \ --cc=paul@xen.org \ --cc=ross.lagerwall@citrix.com \ --cc=sstabellini@kernel.org \ --cc=wei.liu@kernel.org \ --cc=xen-devel@lists.xen.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.