summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Horman <nhorman@tuxdriver.com>2014-05-08 12:40:44 -0400
committerJosh Boyer <jwboyer@fedoraproject.org>2014-05-08 15:07:02 -0400
commit81e2ccddf65cd1e654995389bc894d2f4eb640e8 (patch)
tree06080bc6d711683096aae3d197dc4ffbee1c8e1b
parent70b6f2e94b1b0490472e8d1d06571ec4e96b7208 (diff)
downloadkernel-81e2ccddf65cd1e654995389bc894d2f4eb640e8.tar.gz
kernel-81e2ccddf65cd1e654995389bc894d2f4eb640e8.tar.xz
kernel-81e2ccddf65cd1e654995389bc894d2f4eb640e8.zip
Resolves bz 1082266
-rw-r--r--jme-fix-dma-unmap-error.patch124
-rw-r--r--kernel.spec8
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)