[PATCH 2/2] ath25: eth: fix crash on skb DMA (un-)map

Sergey Ryazanov ryazanov.s.a at gmail.com
Thu Sep 3 20:20:51 EDT 2020


AR2315 Ethernet driver pass NULL instead of a real device pointer to DMA
(un-)map calls. With kernel version 5.4 such behaviour causes a kernel
panic. Fix this issue by preserving device pointer during the probe
procedure and pass it to each skb data DMA (un-)map call.

Signed-off-by: Sergey Ryazanov <ryazanov.s.a at gmail.com>
---
 .../linux/ath25/patches-5.4/110-ar2313_ethernet.patch  | 10 ++++++----
 .../ath25/patches-5.4/220-enet_micrel_workaround.patch | 10 +++++-----
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/target/linux/ath25/patches-5.4/110-ar2313_ethernet.patch b/target/linux/ath25/patches-5.4/110-ar2313_ethernet.patch
index e4f5fa8d2e..57c18abf69 100644
--- a/target/linux/ath25/patches-5.4/110-ar2313_ethernet.patch
+++ b/target/linux/ath25/patches-5.4/110-ar2313_ethernet.patch
@@ -33,7 +33,7 @@
 +obj-$(CONFIG_NET_AR231X) += ar231x.o
 --- /dev/null
 +++ b/drivers/net/ethernet/atheros/ar231x/ar231x.c
-@@ -0,0 +1,1119 @@
+@@ -0,0 +1,1120 @@
 +/*
 + * ar231x.c: Linux driver for the Atheros AR231x Ethernet device.
 + *
@@ -225,6 +225,7 @@
 +
 +	sp = netdev_priv(dev);
 +	sp->dev = dev;
++	sp->pdev = pdev;
 +	sp->cfg = pdev->dev.platform_data;
 +
 +	sprintf(buf, "eth%d_membase", pdev->id);
@@ -787,7 +788,7 @@
 +			break;
 +		}
 +		/* done with this descriptor */
-+		dma_unmap_single(NULL, txdesc->addr,
++		dma_unmap_single(&sp->pdev->dev, txdesc->addr,
 +				 txdesc->devcs & DMA_TX1_BSIZE_MASK,
 +				 DMA_TO_DEVICE);
 +		txdesc->status = 0;
@@ -1014,7 +1015,7 @@
 +	/* Setup the transmit descriptor. */
 +	td->devcs = ((skb->len << DMA_TX1_BSIZE_SHIFT) |
 +				 (DMA_TX1_LS | DMA_TX1_IC | DMA_TX1_CHAINED));
-+	td->addr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE);
++	td->addr = dma_map_single(&sp->pdev->dev, skb->data, skb->len, DMA_TO_DEVICE);
 +	td->status = DMA_TX_OWN;
 +
 +	/* kick transmitter last */
@@ -1155,7 +1156,7 @@
 +
 --- /dev/null
 +++ b/drivers/net/ethernet/atheros/ar231x/ar231x.h
-@@ -0,0 +1,281 @@
+@@ -0,0 +1,282 @@
 +/*
 + * ar231x.h: Linux driver for the Atheros AR231x Ethernet device.
 + *
@@ -1379,6 +1380,7 @@
 + */
 +struct ar231x_private {
 +	struct net_device *dev;
++	struct platform_device *pdev;
 +	int version;
 +	u32 mb[2];
 +
diff --git a/target/linux/ath25/patches-5.4/220-enet_micrel_workaround.patch b/target/linux/ath25/patches-5.4/220-enet_micrel_workaround.patch
index 91b9792515..9051e1b466 100644
--- a/target/linux/ath25/patches-5.4/220-enet_micrel_workaround.patch
+++ b/target/linux/ath25/patches-5.4/220-enet_micrel_workaround.patch
@@ -41,7 +41,7 @@
  static int ar231x_probe(struct platform_device *pdev)
  {
  	struct net_device *dev;
-@@ -273,6 +300,24 @@ static int ar231x_probe(struct platform_
+@@ -274,6 +301,24 @@ static int ar231x_probe(struct platform_
  
  	mdiobus_register(sp->mii_bus);
  
@@ -66,7 +66,7 @@
  	if (ar231x_mdiobus_probe(dev) != 0) {
  		printk(KERN_ERR "%s: mdiobus_probe failed\n", dev->name);
  		rx_tasklet_cleanup(dev);
-@@ -326,8 +371,10 @@ static int ar231x_remove(struct platform
+@@ -327,8 +372,10 @@ static int ar231x_remove(struct platform
  	rx_tasklet_cleanup(dev);
  	ar231x_init_cleanup(dev);
  	unregister_netdev(dev);
@@ -79,7 +79,7 @@
  	kfree(dev);
  	return 0;
  }
-@@ -870,7 +917,8 @@ static int ar231x_open(struct net_device
+@@ -871,7 +918,8 @@ static int ar231x_open(struct net_device
  
  	sp->eth_regs->mac_control |= MAC_CONTROL_RE;
  
@@ -89,7 +89,7 @@
  
  	return 0;
  }
-@@ -951,7 +999,8 @@ static int ar231x_close(struct net_devic
+@@ -952,7 +1000,8 @@ static int ar231x_close(struct net_devic
  
  #endif
  
@@ -99,7 +99,7 @@
  
  	return 0;
  }
-@@ -995,6 +1044,9 @@ static int ar231x_ioctl(struct net_devic
+@@ -996,6 +1045,9 @@ static int ar231x_ioctl(struct net_devic
  {
  	struct ar231x_private *sp = netdev_priv(dev);
  
-- 
2.26.2




More information about the openwrt-devel mailing list