All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net] skge: add dma_mapping check
@ 2013-08-05  0:22 Stephen Hemminger
  2013-08-05  1:35 ` David Miller
  0 siblings, 1 reply; 25+ messages in thread
From: Stephen Hemminger @ 2013-08-05  0:22 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

This old driver never checked for DMA mapping errors.
Causing splats with the new DMA mapping checks:
	WARNING: at lib/dma-debug.c:937 check_unmap+0x47b/0x930()
	skge 0000:01:09.0: DMA-API: device driver failed to check map

Add checks and unwind code.

Reported-by: poma <pomidorabelisima@gmail.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>


--- a/drivers/net/ethernet/marvell/skge.c	2013-08-04 11:03:20.842978549 -0700
+++ b/drivers/net/ethernet/marvell/skge.c	2013-08-04 17:08:19.256002544 -0700
@@ -931,15 +931,18 @@ static int skge_ring_alloc(struct skge_r
 }
 
 /* Allocate and setup a new buffer for receiving */
-static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
+static int skge_rx_setup(struct skge_port *skge, struct skge_element *e,
 			  struct sk_buff *skb, unsigned int bufsize)
 {
 	struct skge_rx_desc *rd = e->desc;
-	u64 map;
+	dma_addr_t map;
 
 	map = pci_map_single(skge->hw->pdev, skb->data, bufsize,
 			     PCI_DMA_FROMDEVICE);
 
+	if (pci_dma_mapping_error(skge->hw->pdev, map))
+		return -1;
+
 	rd->dma_lo = map;
 	rd->dma_hi = map >> 32;
 	e->skb = skb;
@@ -953,6 +956,7 @@ static void skge_rx_setup(struct skge_po
 	rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize;
 	dma_unmap_addr_set(e, mapaddr, map);
 	dma_unmap_len_set(e, maplen, bufsize);
+	return 0;
 }
 
 /* Resume receiving using existing skb,
@@ -1014,7 +1018,10 @@ static int skge_rx_fill(struct net_devic
 			return -ENOMEM;
 
 		skb_reserve(skb, NET_IP_ALIGN);
-		skge_rx_setup(skge, e, skb, skge->rx_buf_size);
+		if (skge_rx_setup(skge, e, skb, skge->rx_buf_size) < 0) {
+			dev_kfree_skb(skb);
+			return -EIO;
+		}
 	} while ((e = e->next) != ring->start);
 
 	ring->to_clean = ring->start;
@@ -2729,7 +2736,7 @@ static netdev_tx_t skge_xmit_frame(struc
 	struct skge_tx_desc *td;
 	int i;
 	u32 control, len;
-	u64 map;
+	dma_addr_t map;
 
 	if (skb_padto(skb, ETH_ZLEN))
 		return NETDEV_TX_OK;
@@ -2743,6 +2750,9 @@ static netdev_tx_t skge_xmit_frame(struc
 	e->skb = skb;
 	len = skb_headlen(skb);
 	map = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(hw->pdev, map))
+		goto mapping_error;
+
 	dma_unmap_addr_set(e, mapaddr, map);
 	dma_unmap_len_set(e, maplen, len);
 
@@ -2778,6 +2788,8 @@ static netdev_tx_t skge_xmit_frame(struc
 
 			map = skb_frag_dma_map(&hw->pdev->dev, frag, 0,
 					       skb_frag_size(frag), DMA_TO_DEVICE);
+			if (dma_mapping_error(&hw->pdev->dev, map))
+				goto mapping_unwind;
 
 			e = e->next;
 			e->skb = skb;
@@ -2815,6 +2827,26 @@ static netdev_tx_t skge_xmit_frame(struc
 	}
 
 	return NETDEV_TX_OK;
+
+mapping_unwind:
+	e = skge->tx_ring.to_use;
+	pci_unmap_single(hw->pdev,
+			 dma_unmap_addr(e, mapaddr),
+			 dma_unmap_len(e, maplen),
+			 PCI_DMA_TODEVICE);
+	while (i-- > 0) {
+		e = e->next;
+		pci_unmap_page(hw->pdev,
+			       dma_unmap_addr(e, mapaddr),
+			       dma_unmap_len(e, maplen),
+			       PCI_DMA_TODEVICE);
+	}
+
+mapping_error:
+	if (net_ratelimit())
+		dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
 }
 
 
@@ -3058,13 +3090,17 @@ static struct sk_buff *skge_rx_get(struc
 		if (!nskb)
 			goto resubmit;
 
+		if (skge_rx_setup(skge, e, nskb, skge->rx_buf_size) < 0) {
+			dev_kfree_skb(nskb);
+			goto resubmit;
+		}
+
 		pci_unmap_single(skge->hw->pdev,
 				 dma_unmap_addr(e, mapaddr),
 				 dma_unmap_len(e, maplen),
 				 PCI_DMA_FROMDEVICE);
 		skb = e->skb;
 		prefetch(skb->data);
-		skge_rx_setup(skge, e, nskb, skge->rx_buf_size);
 	}
 
 	skb_put(skb, len);

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2013-08-22 14:46 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-05  0:22 [PATCH net] skge: add dma_mapping check Stephen Hemminger
2013-08-05  1:35 ` David Miller
2013-08-05  3:40   ` [PATCH net] skge: fix build on 32 bit Stephen Hemminger
2013-08-05  6:37     ` David Miller
2013-08-10 11:51   ` [PATCH net] skge: add dma_mapping check poma
2013-08-10 17:41     ` Stephen Hemminger
2013-08-10 20:29       ` David Miller
2013-08-10 22:02         ` [PATCH net] skge: dma_sync the whole receive buffer Stephen Hemminger
2013-08-11  4:23           ` poma
2013-08-13 22:09           ` David Miller
2013-08-13 22:20             ` Stephen Hemminger
2013-08-14  1:00             ` Stephen Hemminger
2013-08-14 10:20               ` poma
2013-08-14 16:20                 ` Stephen Hemminger
2013-08-14 18:29                   ` poma
2013-08-15 15:41                     ` Stephen Hemminger
2013-08-16 14:36                       ` poma
2013-08-19  0:49                       ` poma
2013-08-20  3:28                         ` poma
2013-08-21 16:04                           ` poma
2013-08-22  0:40                             ` Greg KH
2013-08-22  3:30                               ` poma
2013-08-22  4:00                                 ` Greg KH
2013-08-22 14:46                                   ` poma
2013-08-22  4:08                                 ` Stephen Hemminger

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.