⬢ DragonFlyBSD Kernel Audit
DF-4259 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/netif/my/if_my.c b/sys/dev/netif/my/if_my.c
index 1111111..2222222 100644
--- a/sys/dev/netif/my/if_my.c
+++ b/sys/dev/netif/my/if_my.c
@@ -1646,9 +1646,19 @@ my_stop(struct my_softc * sc)
 
 	ifp->if_timer = 0;
 
+	/*
+	 * Put the transmit and receive logic in the idle state and wait
+	 * for the engines to actually stop before freeing the buffers,
+	 * otherwise an in-flight DMA can write into freed mbuf clusters.
+	 */
 	MY_CLRBIT(sc, MY_TCRRCR, (MY_RE | MY_TE));
+	for (i = 0; i < MY_TIMEOUT; i++) {
+		DELAY(10);
+		if (!(CSR_READ_4(sc, MY_TCRRCR) & (MY_TXRUN | MY_RXRUN)))
+			break;
+	}
+	if (i == MY_TIMEOUT)
+		kprintf("my%d: failed to force tx and rx to idle\n",
+		    sc->my_unit);
 	CSR_WRITE_4(sc, MY_IMR, 0x00000000);
 	CSR_WRITE_4(sc, MY_TXLBA, 0x00000000);
 	CSR_WRITE_4(sc, MY_RXLBA, 0x00000000);