diff options
author | Anton Blanchard <anton@samba.org> | 2011-09-07 10:41:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-09-16 15:26:32 -0400 |
commit | b93da27f5234198433345e40b39ff59797bc6f6e (patch) | |
tree | 96152ec145b0e749e1573a624342c27d48a6b190 /drivers/net/ibmveth.c | |
parent | 33a48ab105a75d37021e422a0a3283241099b142 (diff) |
ibmveth: Fix issue with DMA mapping failure
descs[].fields.address is 32bit which truncates any dma mapping
errors so dma_mapping_error() fails to catch it.
Use a dma_addr_t to do the comparison. With this patch I was able
to transfer many gigabytes of data with IOMMU fault injection set
at 10% probability.
Signed-off-by: Anton Blanchard <anton@samba.org>
Cc: <stable@kernel.org> # v2.6.37+
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ibmveth.c')
-rw-r--r-- | drivers/net/ibmveth.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index dcf65d8f10d2..5b8b411d5a80 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -930,6 +930,7 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, | |||
930 | union ibmveth_buf_desc descs[6]; | 930 | union ibmveth_buf_desc descs[6]; |
931 | int last, i; | 931 | int last, i; |
932 | int force_bounce = 0; | 932 | int force_bounce = 0; |
933 | dma_addr_t dma_addr; | ||
933 | 934 | ||
934 | /* | 935 | /* |
935 | * veth handles a maximum of 6 segments including the header, so | 936 | * veth handles a maximum of 6 segments including the header, so |
@@ -994,17 +995,16 @@ retry_bounce: | |||
994 | } | 995 | } |
995 | 996 | ||
996 | /* Map the header */ | 997 | /* Map the header */ |
997 | descs[0].fields.address = dma_map_single(&adapter->vdev->dev, skb->data, | 998 | dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, |
998 | skb_headlen(skb), | 999 | skb_headlen(skb), DMA_TO_DEVICE); |
999 | DMA_TO_DEVICE); | 1000 | if (dma_mapping_error(&adapter->vdev->dev, dma_addr)) |
1000 | if (dma_mapping_error(&adapter->vdev->dev, descs[0].fields.address)) | ||
1001 | goto map_failed; | 1001 | goto map_failed; |
1002 | 1002 | ||
1003 | descs[0].fields.flags_len = desc_flags | skb_headlen(skb); | 1003 | descs[0].fields.flags_len = desc_flags | skb_headlen(skb); |
1004 | descs[0].fields.address = dma_addr; | ||
1004 | 1005 | ||
1005 | /* Map the frags */ | 1006 | /* Map the frags */ |
1006 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | 1007 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
1007 | unsigned long dma_addr; | ||
1008 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 1008 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
1009 | 1009 | ||
1010 | dma_addr = dma_map_page(&adapter->vdev->dev, frag->page, | 1010 | dma_addr = dma_map_page(&adapter->vdev->dev, frag->page, |