From e8a308affcd79d95dad111f7872e43e9f73abb3b Mon Sep 17 00:00:00 2001 From: Kiran Padwal Date: Thu, 5 Feb 2015 17:01:37 +0530 Subject: ARCNET: Add missing error check for devm_kzalloc This patch add a missing check on the return value of devm_kzalloc, which would cause a NULL pointer dereference in a OOM situation. Signed-off-by: Kiran Padwal Signed-off-by: David S. Miller --- drivers/net/arcnet/com20020-pci.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c index 6c99ff0b0bdd..945f532078e9 100644 --- a/drivers/net/arcnet/com20020-pci.c +++ b/drivers/net/arcnet/com20020-pci.c @@ -78,6 +78,9 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i priv = devm_kzalloc(&pdev->dev, sizeof(struct com20020_priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + ci = (struct com20020_pci_card_info *)id->driver_data; priv->ci = ci; -- cgit v1.2.3 From 37c85c3498c5538db050ff287e346127dbc16f7c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 5 Feb 2015 11:00:42 +0300 Subject: net: sxgbe: fix error handling in init_rx_ring() There are a couple bugs with the error handling in this function. 1) If we can't allocate "rx_ring->rx_skbuff" then we should call dma_free_coherent() but we don't. 2) free_rx_ring() frees "rx_ring->rx_skbuff_dma" and "rx_ring->rx_skbuff" so calling it in a loop causes a double free. Also it was a bit confusing how we sometimes freed things before doing the goto. I've cleaned it up so it does error handling in normal kernel style. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 57 +++++++++++++++++++------ 1 file changed, 43 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index b1a271853d85..d860dca01475 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -365,6 +365,26 @@ static int sxgbe_init_rx_buffers(struct net_device *dev, return 0; } + +/** + * sxgbe_free_rx_buffers - free what sxgbe_init_rx_buffers() allocated + * @dev: net device structure + * @rx_ring: ring to be freed + * @rx_rsize: ring size + * Description: this function initializes the DMA RX descriptor + */ +static void sxgbe_free_rx_buffers(struct net_device *dev, + struct sxgbe_rx_norm_desc *p, int i, + unsigned int dma_buf_sz, + struct sxgbe_rx_queue *rx_ring) +{ + struct sxgbe_priv_data *priv = netdev_priv(dev); + + kfree_skb(rx_ring->rx_skbuff[i]); + dma_unmap_single(priv->device, rx_ring->rx_skbuff_dma[i], + dma_buf_sz, DMA_FROM_DEVICE); +} + /** * init_tx_ring - init the TX descriptor ring * @dev: net device structure @@ -457,7 +477,7 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, /* RX ring is not allcoated */ if (rx_ring == NULL) { netdev_err(dev, "No memory for RX queue\n"); - goto error; + return -ENOMEM; } /* assign queue number */ @@ -469,23 +489,21 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, &rx_ring->dma_rx_phy, GFP_KERNEL); if (rx_ring->dma_rx == NULL) - goto error; + return -ENOMEM; /* allocate memory for RX skbuff array */ rx_ring->rx_skbuff_dma = kmalloc_array(rx_rsize, sizeof(dma_addr_t), GFP_KERNEL); if (!rx_ring->rx_skbuff_dma) { - dma_free_coherent(priv->device, - rx_rsize * sizeof(struct sxgbe_rx_norm_desc), - rx_ring->dma_rx, rx_ring->dma_rx_phy); - goto error; + ret = -ENOMEM; + goto err_free_dma_rx; } rx_ring->rx_skbuff = kmalloc_array(rx_rsize, sizeof(struct sk_buff *), GFP_KERNEL); if (!rx_ring->rx_skbuff) { - kfree(rx_ring->rx_skbuff_dma); - goto error; + ret = -ENOMEM; + goto err_free_skbuff_dma; } /* initialise the buffers */ @@ -495,7 +513,7 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, ret = sxgbe_init_rx_buffers(dev, p, desc_index, bfsize, rx_ring); if (ret) - goto err_init_rx_buffers; + goto err_free_rx_buffers; } /* initalise counters */ @@ -505,11 +523,22 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, return 0; -err_init_rx_buffers: - while (--desc_index >= 0) - free_rx_ring(priv->device, rx_ring, desc_index); -error: - return -ENOMEM; +err_free_rx_buffers: + while (--desc_index >= 0) { + struct sxgbe_rx_norm_desc *p; + + p = rx_ring->dma_rx + desc_index; + sxgbe_free_rx_buffers(dev, p, desc_index, bfsize, rx_ring); + } + kfree(rx_ring->rx_skbuff); +err_free_skbuff_dma: + kfree(rx_ring->rx_skbuff_dma); +err_free_dma_rx: + dma_free_coherent(priv->device, + rx_rsize * sizeof(struct sxgbe_rx_norm_desc), + rx_ring->dma_rx, rx_ring->dma_rx_phy); + + return ret; } /** * free_tx_ring - free the TX descriptor ring -- cgit v1.2.3 From 6e0ba47f9191511a91556b7ca2c491362680a0f3 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Thu, 5 Feb 2015 14:52:06 +0100 Subject: dsa: do not dereference non-existing routing table In the case where there is only one switch, no routing table will have been allocated, so do not dereference it in this case. Signed-off-by: Tobias Waldekranz Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6131.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 1230f52aa70e..2540ef0142af 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -139,7 +139,8 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) int nexthop; nexthop = 0x1f; - if (i != ds->index && i < ds->dst->pd->nr_chips) + if (ds->pd->rtable && + i != ds->index && i < ds->dst->pd->nr_chips) nexthop = ds->pd->rtable[i] & 0x1f; REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | nexthop); -- cgit v1.2.3 From fd972b736bfec7e0297dac9501211abb91b436fd Mon Sep 17 00:00:00 2001 From: "Lendacky, Thomas" Date: Thu, 5 Feb 2015 19:17:14 -0600 Subject: amd-xgbe: Check per channel DMA interrupt use in main ISR When using per channel DMA interrupts the transmit interrupt (TI) and the receive interrupt (RI) are masked off so as to not generate an interrupt to the main ISR. However, should another interrupt fire for the DMA channel that is handled by the main ISR the TI/RI bits can still be set. This will cause the wrong and uninitialized napi structure to be used causing a panic. Add a check to be sure per channel DMA interrupts are not enabled before acting on those bit flags. Signed-off-by: Tom Lendacky Signed-off-by: David S. Miller --- drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index e5ffb2ccb67d..477a7e35d21a 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -337,12 +337,13 @@ static irqreturn_t xgbe_isr(int irq, void *data) dma_ch_isr = XGMAC_DMA_IOREAD(channel, DMA_CH_SR); DBGPR(" DMA_CH%u_ISR = %08x\n", i, dma_ch_isr); - /* If we get a TI or RI interrupt that means per channel DMA - * interrupts are not enabled, so we use the private data napi - * structure, not the per channel napi structure + /* The TI or RI interrupt bits may still be set even if using + * per channel DMA interrupts. Check to be sure those are not + * enabled before using the private data napi structure. */ - if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, TI) || - XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RI)) { + if (!pdata->per_channel_irq && + (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, TI) || + XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RI))) { if (napi_schedule_prep(&pdata->napi)) { /* Disable Tx and Rx interrupts */ xgbe_disable_rx_tx_ints(pdata); -- cgit v1.2.3 From a4870f79c228d109c1e51df4a899394515271604 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Sat, 7 Feb 2015 03:17:31 +0100 Subject: vxlan: Wrong type passed to %pIS src_ip is a pointer to a union vxlan_addr, one member of which is a struct sockaddr. Passing a pointer to src_ip is wrong; one should pass the value of src_ip itself. Since %pIS formally expects something of type struct sockaddr*, let's pass a pointer to the appropriate union member, though this of course doesn't change the generated code. Fixes: e4c7ed415387 ("vxlan: add ipv6 support") Signed-off-by: Rasmus Villemoes Acked-by: Cong Wang Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index a8c755dcab14..11defbb24183 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -991,7 +991,7 @@ static bool vxlan_snoop(struct net_device *dev, if (net_ratelimit()) netdev_info(dev, "%pM migrated from %pIS to %pIS\n", - src_mac, &rdst->remote_ip, &src_ip); + src_mac, &rdst->remote_ip.sa, &src_ip->sa); rdst->remote_ip = *src_ip; f->updated = jiffies; -- cgit v1.2.3