aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/genet/bcmgenet.c
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2014-09-08 14:37:52 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-08 19:02:49 -0400
commitb629be5c8399d7c423b92135eb43a86c924d1cbc (patch)
tree28483cec84c56b551a51d19a25d5479ea948aae5 /drivers/net/ethernet/broadcom/genet/bcmgenet.c
parentfe24ba082b8483c81f546d24e40a55624295b85d (diff)
net: bcmgenet: check harder for out of memory conditions
There is a potential case where we might be failing to refill a control block, leaving it with both a NULL skb pointer *and* a NULL dma_unmap_addr. The way we process incoming packets, by first calling dma_unmap_single(), and then only checking for a potential NULL skb can lead to situations where do pass a NULL dma_unmap_addr() to dma_unmap_single(), resulting in an oops. Fix this my moving the NULL skb check earlier, since no backing skb also means no corresponding DMA mapping for this packet. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/genet/bcmgenet.c')
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 3f9d4de8173c..cdef86a03862 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1274,12 +1274,29 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
1274 1274
1275 while ((rxpktprocessed < rxpkttoprocess) && 1275 while ((rxpktprocessed < rxpkttoprocess) &&
1276 (rxpktprocessed < budget)) { 1276 (rxpktprocessed < budget)) {
1277 cb = &priv->rx_cbs[priv->rx_read_ptr];
1278 skb = cb->skb;
1279
1280 rxpktprocessed++;
1281
1282 priv->rx_read_ptr++;
1283 priv->rx_read_ptr &= (priv->num_rx_bds - 1);
1284
1285 /* We do not have a backing SKB, so we do not have a
1286 * corresponding DMA mapping for this incoming packet since
1287 * bcmgenet_rx_refill always either has both skb and mapping or
1288 * none.
1289 */
1290 if (unlikely(!skb)) {
1291 dev->stats.rx_dropped++;
1292 dev->stats.rx_errors++;
1293 goto refill;
1294 }
1295
1277 /* Unmap the packet contents such that we can use the 1296 /* Unmap the packet contents such that we can use the
1278 * RSV from the 64 bytes descriptor when enabled and save 1297 * RSV from the 64 bytes descriptor when enabled and save
1279 * a 32-bits register read 1298 * a 32-bits register read
1280 */ 1299 */
1281 cb = &priv->rx_cbs[priv->rx_read_ptr];
1282 skb = cb->skb;
1283 dma_unmap_single(&dev->dev, dma_unmap_addr(cb, dma_addr), 1300 dma_unmap_single(&dev->dev, dma_unmap_addr(cb, dma_addr),
1284 priv->rx_buf_len, DMA_FROM_DEVICE); 1301 priv->rx_buf_len, DMA_FROM_DEVICE);
1285 1302
@@ -1307,18 +1324,6 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
1307 __func__, p_index, priv->rx_c_index, 1324 __func__, p_index, priv->rx_c_index,
1308 priv->rx_read_ptr, dma_length_status); 1325 priv->rx_read_ptr, dma_length_status);
1309 1326
1310 rxpktprocessed++;
1311
1312 priv->rx_read_ptr++;
1313 priv->rx_read_ptr &= (priv->num_rx_bds - 1);
1314
1315 /* out of memory, just drop packets at the hardware level */
1316 if (unlikely(!skb)) {
1317 dev->stats.rx_dropped++;
1318 dev->stats.rx_errors++;
1319 goto refill;
1320 }
1321
1322 if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) { 1327 if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) {
1323 netif_err(priv, rx_status, dev, 1328 netif_err(priv, rx_status, dev,
1324 "dropping fragmented packet!\n"); 1329 "dropping fragmented packet!\n");