aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2010-02-17 10:16:54 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-17 20:27:34 -0500
commit61e800cf949926b3d463ca3cf3025d964872774b (patch)
treeb855725b34c8b1f6b31b50052e2596a9797fcf96
parent99405162598176e830d17ae6d4f3d9e070ad900c (diff)
tg3: Enforce DMA mapping / skb assignment ordering
Michael Chan noted that there is nothing in the code that would prevent the compiler from delaying the access of the "mapping" member of the newly arrived packet until much later. If this happened after the skb = NULL assignment, it is possible for the driver to pass a bad dma_addr value to pci_unmap_single(). To enforce this ordering, we need a write memory barrier. The pairing read memory barrier already exists in tg3_rx_prodring_xfer() under the comments starting with "Ensure that updates to the...". Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/tg3.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 385434ff3960..344490e872b4 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -4659,11 +4659,16 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
4659 if (skb_size < 0) 4659 if (skb_size < 0)
4660 goto drop_it; 4660 goto drop_it;
4661 4661
4662 ri->skb = NULL;
4663
4664 pci_unmap_single(tp->pdev, dma_addr, skb_size, 4662 pci_unmap_single(tp->pdev, dma_addr, skb_size,
4665 PCI_DMA_FROMDEVICE); 4663 PCI_DMA_FROMDEVICE);
4666 4664
4665 /* Ensure that the update to the skb happens
4666 * after the usage of the old DMA mapping.
4667 */
4668 smp_wmb();
4669
4670 ri->skb = NULL;
4671
4667 skb_put(skb, len); 4672 skb_put(skb, len);
4668 } else { 4673 } else {
4669 struct sk_buff *copy_skb; 4674 struct sk_buff *copy_skb;