igc: Fix infinite loop in release_swfw_sync
authorSasha Neftin <sasha.neftin@intel.com>
Tue, 1 Mar 2022 13:32:10 +0000 (15:32 +0200)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Wed, 13 Apr 2022 14:58:32 +0000 (07:58 -0700)
An infinite loop may occur if we fail to acquire the HW semaphore,
which is needed for resource release.
This will typically happen if the hardware is surprise-removed.
At this stage there is nothing to do, except log an error and quit.

Fixes: c0071c7aa5fe ("igc: Add HW initialization code")
Suggested-by: Dima Ruinskiy <dima.ruinskiy@intel.com>
Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
Tested-by: Naama Meir <naamax.meir@linux.intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/igc/igc_i225.c

index 66ea566..59d5c46 100644 (file)
@@ -156,8 +156,15 @@ void igc_release_swfw_sync_i225(struct igc_hw *hw, u16 mask)
 {
        u32 swfw_sync;
 
-       while (igc_get_hw_semaphore_i225(hw))
-               ; /* Empty */
+       /* Releasing the resource requires first getting the HW semaphore.
+        * If we fail to get the semaphore, there is nothing we can do,
+        * except log an error and quit. We are not allowed to hang here
+        * indefinitely, as it may cause denial of service or system crash.
+        */
+       if (igc_get_hw_semaphore_i225(hw)) {
+               hw_dbg("Failed to release SW_FW_SYNC.\n");
+               return;
+       }
 
        swfw_sync = rd32(IGC_SW_FW_SYNC);
        swfw_sync &= ~mask;