]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
eth: fbnic: take netif_addr_lock_bh() around rx mode address programming
authorDaniel Zahka <daniel.zahka@gmail.com>
Wed, 17 Jun 2026 10:39:49 +0000 (03:39 -0700)
committerJakub Kicinski <kuba@kernel.org>
Fri, 19 Jun 2026 01:36:26 +0000 (18:36 -0700)
When __fbnic_set_rx_mode() is called from contexts other than
.ndo_set_rx_mode_async(), the uc and mc addr lists are accessed
without the addr lock that __hw_addr_sync_dev() and
__hw_addr_unsync_dev() require. Wrap these unprotected accesses with
netif_addr_lock_bh(). fbnic_clear_rx_mode() has similar issues.

Fixes: eb690ef8d1c2 ("eth: fbnic: Add L2 address programming")
Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260617-linux-fbnic-hwaddr-v1-1-3f9f5dee7f99@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
drivers/net/ethernet/meta/fbnic/fbnic_pci.c
drivers/net/ethernet/meta/fbnic/fbnic_rpc.c

index dd77ab6052c88247ff9ae4c7110ea3ad4c1cc292..10bf99be3f244859d5215e2e6253a75942a41388 100644 (file)
@@ -264,8 +264,11 @@ static int fbnic_set_mac(struct net_device *netdev, void *p)
 
        eth_hw_addr_set(netdev, addr->sa_data);
 
-       if (netif_running(netdev))
+       if (netif_running(netdev)) {
+               netif_addr_lock_bh(netdev);
                __fbnic_set_rx_mode(fbn->fbd, &netdev->uc, &netdev->mc);
+               netif_addr_unlock_bh(netdev);
+       }
 
        return 0;
 }
@@ -310,8 +313,10 @@ void fbnic_clear_rx_mode(struct fbnic_dev *fbd)
        /* Write updates to hardware */
        fbnic_write_macda(fbd);
 
+       netif_addr_lock_bh(netdev);
        __dev_uc_unsync(netdev, NULL);
        __dev_mc_unsync(netdev, NULL);
+       netif_addr_unlock_bh(netdev);
 }
 
 static int fbnic_hwtstamp_get(struct net_device *netdev,
index 7e85b480203c8341c42a193549f724b750a433f2..8b9bc9e8ea56ca592dd7b7d523920958a3fd1d2f 100644 (file)
@@ -135,7 +135,9 @@ void fbnic_up(struct fbnic_net *fbn)
 
        fbnic_rss_reinit_hw(fbn->fbd, fbn);
 
+       netif_addr_lock_bh(fbn->netdev);
        __fbnic_set_rx_mode(fbn->fbd, &fbn->netdev->uc, &fbn->netdev->mc);
+       netif_addr_unlock_bh(fbn->netdev);
 
        /* Enable Tx/Rx processing */
        fbnic_napi_enable(fbn);
@@ -180,7 +182,9 @@ static int fbnic_fw_config_after_crash(struct fbnic_dev *fbd)
        }
 
        fbnic_rpc_reset_valid_entries(fbd);
+       netif_addr_lock_bh(fbd->netdev);
        __fbnic_set_rx_mode(fbd, &fbd->netdev->uc, &fbd->netdev->mc);
+       netif_addr_unlock_bh(fbd->netdev);
 
        return 0;
 }
index fe95b6f69646327955c90aadc2026d684d2c20ae..bc0f38b6a2b2b474fd723a2eace65393aeff16f3 100644 (file)
@@ -244,7 +244,9 @@ void fbnic_bmc_rpc_check(struct fbnic_dev *fbd)
 
        if (fbd->fw_cap.need_bmc_tcam_reinit) {
                fbnic_bmc_rpc_init(fbd);
+               netif_addr_lock_bh(fbd->netdev);
                __fbnic_set_rx_mode(fbd, &fbd->netdev->uc, &fbd->netdev->mc);
+               netif_addr_unlock_bh(fbd->netdev);
                fbd->fw_cap.need_bmc_tcam_reinit = false;
        }