⬢ DragonFlyBSD Kernel Audit
DF-3826 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/ig_hal/e1000_82575.c
+++ b/sys/dev/netif/ig_hal/e1000_82575.c
@@ -3341,7 +3341,15 @@
 
 	} while (retry < max_retry);
 
-	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+	/* The fail: path above already released the semaphore for every
+	 * failed attempt; releasing again here would clear a SW_FW_SYNC bit
+	 * this function no longer owns (it may have been re-acquired by
+	 * another port or the NVM path during the retry delays).  Release
+	 * only when we exited the loop via break, i.e. the transfer
+	 * succeeded and the semaphore is still held.
+	 */
+	if (status == E1000_SUCCESS)
+		hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 
 read_byte_out: