FAILED: patch "[PATCH] net: bcmgenet: synchronize UMAC_CMD access" failed to apply to 5.15-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 0d5e2a82232605b337972fb2c7d0cbc46898aca1
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024051352-twins-rumor-dcc9@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
0d5e2a822326 ("net: bcmgenet: synchronize UMAC_CMD access") a9f31047baca ("net: bcmgenet: Fix EEE implementation") 53243d412ec5 ("net: use bool values to pass bool param of phy_init_eee()") fc13d8c03773 ("net: bcmgenet: pull mac_config from adjust_link") fcb5dfe7dc40 ("net: bcmgenet: remove old link state values") 50e356686fa9 ("net: bcmgenet: remove netif_carrier_off from adjust_link") b972b54a68b2 ("net: bcmgenet: Patch PHY interface for dedicated PHY driver")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 0d5e2a82232605b337972fb2c7d0cbc46898aca1 Mon Sep 17 00:00:00 2001
From: Doug Berger <[email protected]>
Date: Thu, 25 Apr 2024 15:27:21 -0700
Subject: [PATCH] net: bcmgenet: synchronize UMAC_CMD access
The UMAC_CMD register is written from different execution contexts and has insufficient synchronization protections to prevent possible corruption. Of particular concern are the acceses from the phy_device delayed work context used by the adjust_link call and the BH context that may be used by the ndo_set_rx_mode call.
A spinlock is added to the driver to protect contended register accesses (i.e. reg_lock) and it is used to synchronize accesses to UMAC_CMD.
drivers/net/ethernet/broadcom/genet/bcmgenet.c +11 -1
@@ -2467,14 +2467,18 @@ static void umac_enable_set(struct bcmgenet_priv *priv, u32 mask, bool enable) {u32 reg; +spin_lock_bh (&priv->reg_lock); reg =bcmgenet_umac_readl (priv,UMAC_CMD ); -if (reg &CMD_SW_RESET ) +if (reg &CMD_SW_RESET ) { +spin_unlock_bh (&priv->reg_lock);return ; + }if (enable) reg |= mask;else reg &= ~mask;bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock_bh (&priv->reg_lock);/* UniMAC stops on a packet boundary, wait for a full-size packet * to be processed
@@ -2490,8 +2494,10 @@ static void reset_umac(struct bcmgenet_priv *priv)udelay (10 );/* issue soft reset and disable MAC while updating its registers */ +spin_lock_bh (&priv->reg_lock);bcmgenet_umac_writel (priv,CMD_SW_RESET ,UMAC_CMD );udelay (2 ); +spin_unlock_bh (&priv->reg_lock); }static void bcmgenet_intr_disable (struct bcmgenet_priv *priv)
@@ -3597,16 +3603,19 @@ static void bcmgenet_set_rx_mode(struct net_device *dev)* 3. The number of filters needed exceeds the number filters * supported by the hardware. */ +spin_lock (&priv->reg_lock); reg =bcmgenet_umac_readl (priv,UMAC_CMD );if ((dev->flags & (IFF_PROMISC |IFF_ALLMULTI )) || (nfilter >MAX_MDF_FILTER )) { reg |=CMD_PROMISC ;bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock (&priv->reg_lock);bcmgenet_umac_writel (priv,0 ,UMAC_MDF_CTRL );return ; }else { reg &= ~CMD_PROMISC ;bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock (&priv->reg_lock); }/* update MDF filter */
@@ -4005,6 +4014,7 @@ static int bcmgenet_probe(struct platform_device *pdev) goto err; } +spin_lock_init (&priv->reg_lock);spin_lock_init (&priv->lock);/* Set default pause parameters */
drivers/net/ethernet/broadcom/genet/bcmgenet.h +3 -1
@@ -1,6 +1,6 @@/* SPDX-License-Identifier: GPL-2.0-only */ /* -* Copyright (c) 2014-2020 Broadcom +* Copyright (c) 2014-2024 Broadcom */ #ifndef __BCMGENET_H__
@@ -573,6 +573,8 @@ struct bcmgenet_rxnfc_rule {/* device context */ struct bcmgenet_priv {void __iomem *base; +/* reg_lock: lock to serialize access to shared registers */ +spinlock_t reg_lock;enum bcmgenet_version version;struct net_device *dev;
drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +7 -1
@@ -2,7 +2,7 @@/* * Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support * -* Copyright (c) 2014-2020 Broadcom +* Copyright (c) 2014-2024 Broadcom */ #define pr_fmt (fmt) "bcmgenet_wol: " fmt
@@ -151,6 +151,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, }/* Can't suspend with WoL if MAC is still in reset */ +spin_lock_bh (&priv->reg_lock); reg =bcmgenet_umac_readl (priv,UMAC_CMD );if (reg &CMD_SW_RESET ) reg &= ~CMD_SW_RESET ;
@@ -158,6 +159,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,/* disable RX */ reg &= ~CMD_RX_EN ;bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock_bh (&priv->reg_lock);mdelay (10 );if (priv->wolopts & (WAKE_MAGIC |WAKE_MAGICSECURE )) {
@@ -203,6 +205,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, }/* Enable CRC forward */ +spin_lock_bh (&priv->reg_lock); reg =bcmgenet_umac_readl (priv,UMAC_CMD ); priv->crc_fwd_en =1 ; reg |=CMD_CRC_FWD ;
@@ -210,6 +213,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,/* Receiver must be enabled for WOL MP detection */ reg |=CMD_RX_EN ;bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock_bh (&priv->reg_lock); reg =UMAC_IRQ_MPD_R ;if (hfb_enable)
@@ -256,7 +260,9 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv, }/* Disable CRC Forward */ +spin_lock_bh (&priv->reg_lock); reg =bcmgenet_umac_readl (priv,UMAC_CMD ); reg &= ~CMD_CRC_FWD ;bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock_bh (&priv->reg_lock); }
drivers/net/ethernet/broadcom/genet/bcmmii.c +2 -0
@@ -76,6 +76,7 @@ static void bcmgenet_mac_config(struct net_device *dev) reg |=RGMII_LINK ;bcmgenet_ext_writel (priv, reg,EXT_RGMII_OOB_CTRL ); +spin_lock_bh (&priv->reg_lock); reg =bcmgenet_umac_readl (priv,UMAC_CMD ); reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) | CMD_HD_EN |
@@ -88,6 +89,7 @@ static void bcmgenet_mac_config(struct net_device *dev) reg |=CMD_TX_EN |CMD_RX_EN ; }bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock_bh (&priv->reg_lock); active =phy_init_eee (phydev,0 ) >=0 ; bcmgenet_eee_enable_set(dev,
Doug Berger
maintainerPATCH 1/1 net: bcmgenet: synchronize UMAC_CMD access
The UMAC_CMD register is written from different execution contexts and has insufficient synchronization protections to prevent possible corruption. Of particular concern are the acceses from the phy_device delayed work context used by the adjust_link call and the BH context that may be used by the ndo_set_rx_mode call.
A spinlock is added to the driver to protect contended register accesses (i.e. reg_lock) and it is used to synchronize accesses to UMAC_CMD.
--- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 12 +++++++++++- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 2 ++ drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 6 ++++++ drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 ++ 4 files changed, 21 insertions(+), 1 deletion(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +11 -1
@@ -2424,14 +2424,18 @@ static void umac_enable_set(struct bcmgenet_priv *priv, u32 mask, bool enable) {u32 reg; +spin_lock_bh (&priv->reg_lock); reg =bcmgenet_umac_readl (priv,UMAC_CMD ); -if (reg &CMD_SW_RESET ) +if (reg &CMD_SW_RESET ) { +spin_unlock_bh (&priv->reg_lock);return ; + }if (enable) reg |= mask;else reg &= ~mask;bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock_bh (&priv->reg_lock);/* UniMAC stops on a packet boundary, wait for a full-size packet * to be processed
@@ -2447,8 +2451,10 @@ static void reset_umac(struct bcmgenet_priv *priv)udelay (10 );/* issue soft reset and disable MAC while updating its registers */ +spin_lock_bh (&priv->reg_lock);bcmgenet_umac_writel (priv,CMD_SW_RESET ,UMAC_CMD );udelay (2 ); +spin_unlock_bh (&priv->reg_lock); }static void bcmgenet_intr_disable (struct bcmgenet_priv *priv)
@@ -3566,16 +3572,19 @@ static void bcmgenet_set_rx_mode(struct net_device *dev)* 3. The number of filters needed exceeds the number filters * supported by the hardware. */ +spin_lock (&priv->reg_lock); reg =bcmgenet_umac_readl (priv,UMAC_CMD );if ((dev->flags & (IFF_PROMISC |IFF_ALLMULTI )) || (nfilter >MAX_MDF_FILTER )) { reg |=CMD_PROMISC ;bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock (&priv->reg_lock);bcmgenet_umac_writel (priv,0 ,UMAC_MDF_CTRL );return ; }else { reg &= ~CMD_PROMISC ;bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock (&priv->reg_lock); }/* update MDF filter */
@@ -3969,6 +3978,7 @@ static int bcmgenet_probe(struct platform_device *pdev) goto err; } +spin_lock_init (&priv->reg_lock);spin_lock_init (&priv->lock);SET_NETDEV_DEV (dev, &pdev->dev);
drivers/net/ethernet/broadcom/genet/bcmgenet.h +2 -0
@@ -572,6 +572,8 @@ struct bcmgenet_rxnfc_rule {/* device context */ struct bcmgenet_priv {void __iomem *base; +/* reg_lock: lock to serialize access to shared registers */ +spinlock_t reg_lock;enum bcmgenet_version version;struct net_device *dev;
drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +6 -0
@@ -133,6 +133,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, }/* Can't suspend with WoL if MAC is still in reset */ +spin_lock_bh (&priv->reg_lock); reg =bcmgenet_umac_readl (priv,UMAC_CMD );if (reg &CMD_SW_RESET ) reg &= ~CMD_SW_RESET ;
@@ -140,6 +141,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,/* disable RX */ reg &= ~CMD_RX_EN ;bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock_bh (&priv->reg_lock);mdelay (10 );if (priv->wolopts & (WAKE_MAGIC |WAKE_MAGICSECURE )) {
@@ -185,6 +187,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, }/* Enable CRC forward */ +spin_lock_bh (&priv->reg_lock); reg =bcmgenet_umac_readl (priv,UMAC_CMD ); priv->crc_fwd_en =1 ; reg |=CMD_CRC_FWD ;
@@ -192,6 +195,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,/* Receiver must be enabled for WOL MP detection */ reg |=CMD_RX_EN ;bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock_bh (&priv->reg_lock); reg =UMAC_IRQ_MPD_R ;if (hfb_enable)
@@ -238,7 +242,9 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv, }/* Disable CRC Forward */ +spin_lock_bh (&priv->reg_lock); reg =bcmgenet_umac_readl (priv,UMAC_CMD ); reg &= ~CMD_CRC_FWD ;bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock_bh (&priv->reg_lock); }
drivers/net/ethernet/broadcom/genet/bcmmii.c +2 -0
@@ -91,6 +91,7 @@ void bcmgenet_mii_setup(struct net_device *dev) reg |=RGMII_LINK ;bcmgenet_ext_writel (priv, reg,EXT_RGMII_OOB_CTRL ); +spin_lock_bh (&priv->reg_lock); reg =bcmgenet_umac_readl (priv,UMAC_CMD ); reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) | CMD_HD_EN |
@@ -103,6 +104,7 @@ void bcmgenet_mii_setup(struct net_device *dev) reg |=CMD_TX_EN |CMD_RX_EN ; }bcmgenet_umac_writel (priv, reg,UMAC_CMD ); +spin_unlock_bh (&priv->reg_lock); priv->eee.eee_active =phy_init_eee (phydev,0 ) >=0 ; bcmgenet_eee_enable_set(dev,
Signature · 1 line
2.34.1