Patch "net: adaptec: starfire: add checks for dma mapping errors" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
net: adaptec: starfire: add checks for dma mapping errors
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
net-adaptec-starfire-add-checks-for-dma-mapping-errors.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Thu Jun 15 14:38:52 CEST 2017
From: Alexey Khoroshilov <[email protected]>
Date: Sat, 28 Jan 2017 01:07:30 +0300
Subject: net: adaptec: starfire: add checks for dma mapping errors
From: Alexey Khoroshilov <[email protected]>
[ Upstream commit d1156b489fa734d1af763d6a07b1637c01bb0aed ]
init_ring(), refill_rx_ring() and start_tx() don't check if mapping dma memory succeed.
The patch adds the checks and failure handling.
Found by Linux Driver Verification project (linuxtesting.org).
--- drivers/net/ethernet/adaptec/starfire.c | 45 ++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-)
drivers/net/ethernet/adaptec/starfire.c +43 -2
@@ -1153,6 +1153,12 @@ static void init_ring(struct net_deviceif (skb ==NULL )break ; np->rx_info[i].mapping =pci_map_single (np->pci_dev, skb->data, np->rx_buf_sz,PCI_DMA_FROMDEVICE ); +if (pci_dma_mapping_error (np->pci_dev, + np->rx_info[i].mapping)) { +dev_kfree_skb (skb); + np->rx_info[i].skb =NULL ; +break ; + }/* Grrr, we cannot offset to correctly align the IP header. */ np->rx_ring[i].rxaddr =cpu_to_dma (np->rx_info[i].mapping | RxDescValid); }
@@ -1183,8 +1189,9 @@ static netdev_tx_t start_tx(struct sk_bu {struct netdev_private *np =netdev_priv (dev);unsigned int entry; +unsigned int prev_tx;u32 status; -int i; +int i, j;/* * be cautious here, wrapping the queue has weird semantics
@@ -1202,6 +1209,7 @@ static netdev_tx_t start_tx(struct sk_bu }#endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */ + prev_tx = np->cur_tx; entry = np->cur_tx %TX_RING_SIZE ;for (i =0 ; i <skb_num_frags (skb); i++) {int wrap_ring =0 ;
@@ -1235,6 +1243,11 @@ static netdev_tx_t start_tx(struct sk_buskb_frag_size (this_frag), PCI_DMA_TODEVICE); } +if (pci_dma_mapping_error (np->pci_dev, + np->tx_info[entry].mapping)) { + dev->stats.tx_dropped++; + goto err_out; + } np->tx_ring[entry].addr =cpu_to_dma (np->tx_info[entry].mapping); np->tx_ring[entry].status =cpu_to_le32 (status);
@@ -1269,8 +1282,30 @@ static netdev_tx_t start_tx(struct sk_bunetif_stop_queue (dev);return NETDEV_TX_OK ; -} +err_out: + entry = prev_tx %TX_RING_SIZE ; + np->tx_info[entry].skb =NULL ; +if (i >0 ) { +pci_unmap_single (np->pci_dev, + np->tx_info[entry].mapping, +skb_first_frag_len (skb), +PCI_DMA_TODEVICE ); + np->tx_info[entry].mapping =0 ; + entry = (entry + np->tx_info[entry].used_slots) %TX_RING_SIZE ; +for (j =1 ; j < i; j++) { +pci_unmap_single (np->pci_dev, + np->tx_info[entry].mapping, +skb_frag_size ( + &skb_shinfo (skb)->frags[j-1 ]), +PCI_DMA_TODEVICE ); + entry++; + } + } +dev_kfree_skb_any (skb); + np->cur_tx = prev_tx; +return NETDEV_TX_OK ; +}/* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */
@@ -1570,6 +1605,12 @@ static void refill_rx_ring(struct net_debreak ;/* Better luck next round. */ np->rx_info[entry].mapping =pci_map_single (np->pci_dev, skb->data, np->rx_buf_sz,PCI_DMA_FROMDEVICE ); +if (pci_dma_mapping_error (np->pci_dev, + np->rx_info[entry].mapping)) { +dev_kfree_skb (skb); + np->rx_info[entry].skb =NULL ; +break ; + } np->rx_ring[entry].rxaddr =cpu_to_dma (np->rx_info[entry].mapping | RxDescValid); }
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/net-adaptec-starfire-add-checks-for-dma-mapping-errors.patch