summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorYeounsu Moon <yyyynoom@gmail.com>2025-10-10 00:57:16 +0900
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-10-29 14:03:07 +0100
commit06477bbe26e044c36255f9a11c391b722d7a85f7 (patch)
treef536a0d3815f3a6dd31c4bf444ed28ee5cd5fc72 /drivers
parent97760193e892b8995a2580a1ab08cc4bb6c017c5 (diff)
downloadlinux-06477bbe26e044c36255f9a11c391b722d7a85f7.tar.gz
linux-06477bbe26e044c36255f9a11c391b722d7a85f7.tar.bz2
linux-06477bbe26e044c36255f9a11c391b722d7a85f7.zip
net: dlink: handle dma_map_single() failure properly
[ Upstream commit 65946eac6d888d50ae527c4e5c237dbe5cc3a2f2 ] There is no error handling for `dma_map_single()` failures. Add error handling by checking `dma_mapping_error()` and freeing the `skb` using `dev_kfree_skb()` (process context) when it fails. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com> Tested-on: D-Link DGE-550T Rev-A3 Suggested-by: Simon Horman <horms@kernel.org> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/dlink/dl2k.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
index ca8bfd1b8278..59db32dcf9f3 100644
--- a/drivers/net/ethernet/dlink/dl2k.c
+++ b/drivers/net/ethernet/dlink/dl2k.c
@@ -499,25 +499,34 @@ static int alloc_list(struct net_device *dev)
for (i = 0; i < RX_RING_SIZE; i++) {
/* Allocated fixed size of skbuff */
struct sk_buff *skb;
+ dma_addr_t addr;
skb = netdev_alloc_skb_ip_align(dev, np->rx_buf_sz);
np->rx_skbuff[i] = skb;
- if (!skb) {
- free_list(dev);
- return -ENOMEM;
- }
+ if (!skb)
+ goto err_free_list;
+
+ addr = dma_map_single(&np->pdev->dev, skb->data,
+ np->rx_buf_sz, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&np->pdev->dev, addr))
+ goto err_kfree_skb;
np->rx_ring[i].next_desc = cpu_to_le64(np->rx_ring_dma +
((i + 1) % RX_RING_SIZE) *
sizeof(struct netdev_desc));
/* Rubicon now supports 40 bits of addressing space. */
- np->rx_ring[i].fraginfo =
- cpu_to_le64(dma_map_single(&np->pdev->dev, skb->data,
- np->rx_buf_sz, DMA_FROM_DEVICE));
+ np->rx_ring[i].fraginfo = cpu_to_le64(addr);
np->rx_ring[i].fraginfo |= cpu_to_le64((u64)np->rx_buf_sz << 48);
}
return 0;
+
+err_kfree_skb:
+ dev_kfree_skb(np->rx_skbuff[i]);
+ np->rx_skbuff[i] = NULL;
+err_free_list:
+ free_list(dev);
+ return -ENOMEM;
}
static void rio_hw_init(struct net_device *dev)