diff options
author | Neil Horman <nhorman@tuxdriver.com> | 2014-05-08 12:40:44 -0400 |
---|---|---|
committer | Josh Boyer <jwboyer@fedoraproject.org> | 2014-05-08 15:07:02 -0400 |
commit | 81e2ccddf65cd1e654995389bc894d2f4eb640e8 (patch) | |
tree | 06080bc6d711683096aae3d197dc4ffbee1c8e1b | |
parent | 70b6f2e94b1b0490472e8d1d06571ec4e96b7208 (diff) | |
download | kernel-81e2ccddf65cd1e654995389bc894d2f4eb640e8.tar.gz kernel-81e2ccddf65cd1e654995389bc894d2f4eb640e8.tar.xz kernel-81e2ccddf65cd1e654995389bc894d2f4eb640e8.zip |
Resolves bz 1082266
-rw-r--r-- | jme-fix-dma-unmap-error.patch | 124 | ||||
-rw-r--r-- | kernel.spec | 8 |
2 files changed, 132 insertions, 0 deletions
diff --git a/jme-fix-dma-unmap-error.patch b/jme-fix-dma-unmap-error.patch new file mode 100644 index 00000000..20844728 --- /dev/null +++ b/jme-fix-dma-unmap-error.patch @@ -0,0 +1,124 @@ +diff -up ./drivers/net/ethernet/jme.c.orig ./drivers/net/ethernet/jme.c +--- ./drivers/net/ethernet/jme.c.orig 2014-03-30 23:40:15.000000000 -0400 ++++ ./drivers/net/ethernet/jme.c 2014-05-08 12:16:52.701746091 -0400 +@@ -1988,7 +1988,7 @@ jme_alloc_txdesc(struct jme_adapter *jme + return idx; + } + +-static void ++static int + jme_fill_tx_map(struct pci_dev *pdev, + struct txdesc *txdesc, + struct jme_buffer_info *txbi, +@@ -2005,6 +2005,9 @@ jme_fill_tx_map(struct pci_dev *pdev, + len, + PCI_DMA_TODEVICE); + ++ if (unlikely(pci_dma_mapping_error(pdev, dmaaddr))) ++ return -EINVAL; ++ + pci_dma_sync_single_for_device(pdev, + dmaaddr, + len, +@@ -2021,9 +2024,30 @@ jme_fill_tx_map(struct pci_dev *pdev, + + txbi->mapping = dmaaddr; + txbi->len = len; ++ return 0; + } + +-static void ++static void jme_drop_tx_map(struct jme_adapter *jme, int startidx, int endidx) ++{ ++ struct jme_ring *txring = &(jme->txring[0]); ++ struct jme_buffer_info *txbi = txring->bufinf, *ctxbi; ++ int mask = jme->tx_ring_mask; ++ int j; ++ ++ for (j = startidx ; j < endidx ; ++j) { ++ ctxbi = txbi + ((startidx + j + 2) & (mask)); ++ pci_unmap_page(jme->pdev, ++ ctxbi->mapping, ++ ctxbi->len, ++ PCI_DMA_TODEVICE); ++ ++ ctxbi->mapping = 0; ++ ctxbi->len = 0; ++ } ++ ++} ++ ++static int + jme_map_tx_skb(struct jme_adapter *jme, struct sk_buff *skb, int idx) + { + struct jme_ring *txring = &(jme->txring[0]); +@@ -2034,25 +2058,37 @@ jme_map_tx_skb(struct jme_adapter *jme, + int mask = jme->tx_ring_mask; + const struct skb_frag_struct *frag; + u32 len; ++ int ret = 0; + + for (i = 0 ; i < nr_frags ; ++i) { + frag = &skb_shinfo(skb)->frags[i]; + ctxdesc = txdesc + ((idx + i + 2) & (mask)); + ctxbi = txbi + ((idx + i + 2) & (mask)); + +- jme_fill_tx_map(jme->pdev, ctxdesc, ctxbi, ++ ret = jme_fill_tx_map(jme->pdev, ctxdesc, ctxbi, + skb_frag_page(frag), + frag->page_offset, skb_frag_size(frag), hidma); ++ if (ret) { ++ jme_drop_tx_map(jme, idx, idx+i); ++ goto out; ++ } ++ + } + + len = skb_is_nonlinear(skb) ? skb_headlen(skb) : skb->len; + ctxdesc = txdesc + ((idx + 1) & (mask)); + ctxbi = txbi + ((idx + 1) & (mask)); +- jme_fill_tx_map(jme->pdev, ctxdesc, ctxbi, virt_to_page(skb->data), ++ ret = jme_fill_tx_map(jme->pdev, ctxdesc, ctxbi, virt_to_page(skb->data), + offset_in_page(skb->data), len, hidma); ++ if (ret) ++ jme_drop_tx_map(jme, idx, idx+i); ++ ++out: ++ return ret; + + } + ++ + static int + jme_expand_header(struct jme_adapter *jme, struct sk_buff *skb) + { +@@ -2144,6 +2180,7 @@ jme_fill_tx_desc(struct jme_adapter *jme + struct txdesc *txdesc; + struct jme_buffer_info *txbi; + u8 flags; ++ int ret = 0; + + txdesc = (struct txdesc *)txring->desc + idx; + txbi = txring->bufinf + idx; +@@ -2168,7 +2205,10 @@ jme_fill_tx_desc(struct jme_adapter *jme + if (jme_tx_tso(skb, &txdesc->desc1.mss, &flags)) + jme_tx_csum(jme, skb, &flags); + jme_tx_vlan(skb, &txdesc->desc1.vlan, &flags); +- jme_map_tx_skb(jme, skb, idx); ++ ret = jme_map_tx_skb(jme, skb, idx); ++ if (ret) ++ return ret; ++ + txdesc->desc1.flags = flags; + /* + * Set tx buffer info after telling NIC to send +@@ -2240,7 +2280,8 @@ jme_start_xmit(struct sk_buff *skb, stru + return NETDEV_TX_BUSY; + } + +- jme_fill_tx_desc(jme, skb, idx); ++ if (jme_fill_tx_desc(jme, skb, idx)) ++ return NETDEV_TX_BUSY; + + jwrite32(jme, JME_TXCS, jme->reg_txcs | + TXCS_SELECT_QUEUE0 | diff --git a/kernel.spec b/kernel.spec index ee1c094f..6591314f 100644 --- a/kernel.spec +++ b/kernel.spec @@ -787,6 +787,9 @@ Patch25084: 3-5-net-Add-variants-of-capable-for-use-on-on-sockets.patch Patch25085: 4-5-net-Add-variants-of-capable-for-use-on-netlink-messages.patch Patch25086: 5-5-net-Use-netlink_ns_capable-to-verify-the-permisions-of-netlink-messages.patch +#rhbz 1082266 +Patch25087: jme-fix-dma-unmap-error.patch + # END OF PATCH DEFINITIONS %endif @@ -1527,6 +1530,8 @@ ApplyPatch 3-5-net-Add-variants-of-capable-for-use-on-on-sockets.patch ApplyPatch 4-5-net-Add-variants-of-capable-for-use-on-netlink-messages.patch ApplyPatch 5-5-net-Use-netlink_ns_capable-to-verify-the-permisions-of-netlink-messages.patch +#rhbz 1082266 +ApplyPatch jme-fix-dma-unmap-error.patch # END OF PATCH APPLICATIONS @@ -2339,6 +2344,9 @@ fi # ||----w | # || || %changelog +* Thu May 08 2014 Neil Horman <nhorman@redhat.com> +- Fix dma unmap error in jme driver (rhbz 1082266) + * Tue May 06 2014 Josh Boyer <jwboyer@fedoraproject.org> 3.14.3-200 - CVE-2014-0181 insufficient netlink permission checks (rhbz 1094270 1094265) |