* [PATCH net 3/3] bnxt_en: Restore default stat ctxs for ULP when resource is available
From: Michael Chan @ 2026-03-29 23:25 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, kuba, pabeni, andrew+netdev, pavan.chebbi,
andrew.gospodarek, Kalesh AP
In-Reply-To: <20260329232528.870637-1-michael.chan@broadcom.com>
From: Pavan Chebbi <pavan.chebbi@broadcom.com>
During resource reservation, if the L2 driver does not have enough
MSIX vectors to provide to the RoCE driver, it sets the stat ctxs for
ULP also to 0 so that we don't have to reserve it unnecessarily.
However, subsequently the user may reduce L2 rings thereby freeing up
some resources that the L2 driver can now earmark for RoCE. In this
case, the driver should restore the default ULP stat ctxs to make
sure that all RoCE resources are ready for use.
The RoCE driver may fail to initialize in this scenario without this
fix.
Fixes: d630624ebd70 ("bnxt_en: Utilize ulp client resources if RoCE is not registered")
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index f7be1084b775..5cef54f3d179 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -8045,6 +8045,8 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
ulp_msix = bnxt_get_avail_msix(bp, bp->ulp_num_msix_want);
if (!ulp_msix)
bnxt_set_ulp_stat_ctxs(bp, 0);
+ else
+ bnxt_set_dflt_ulp_stat_ctxs(bp);
if (ulp_msix > bp->ulp_num_msix_want)
ulp_msix = bp->ulp_num_msix_want;
--
2.51.0
^ permalink raw reply related
* [PATCH net 2/3] bnxt_en: Don't assume XDP is never enabled in bnxt_init_dflt_ring_mode()
From: Michael Chan @ 2026-03-29 23:25 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, kuba, pabeni, andrew+netdev, pavan.chebbi,
andrew.gospodarek, Kalesh AP
In-Reply-To: <20260329232528.870637-1-michael.chan@broadcom.com>
The original code made the assumption that when we set up the initial
default ring mode, we must be just loading the driver and XDP cannot
be enabled yet. This is not true when the FW goes through a resource
or capability change. Resource reservations will be cancelled and
reinitialized with XDP already enabled. devlink reload with XDP enabled
will also have the same issue. This scenario will cause the ring
arithmetic to be all wrong in the bnxt_init_dflt_ring_mode() path
causing failure:
bnxt_en 0000:a1:00.0 ens2f0np0: bnxt_setup_int_mode err: ffffffea
bnxt_en 0000:a1:00.0 ens2f0np0: bnxt_request_irq err: ffffffea
bnxt_en 0000:a1:00.0 ens2f0np0: nic open fail (rc: ffffffea)
Fix it by properly accounting for XDP in the bnxt_init_dflt_ring_mode()
path by using the refactored helper functions in the previous patch.
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Fixes: ec5d31e3c15d ("bnxt_en: Handle firmware reset status during IF_UP.")
Fixes: 93550a9c7939 ("bnxt_en: implement devlink dev reload driver_reinit")
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index fa44c86af67b..f7be1084b775 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -16547,6 +16547,10 @@ static void bnxt_adj_dflt_rings(struct bnxt *bp, bool sh)
else
bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+ if (sh && READ_ONCE(bp->xdp_prog)) {
+ bnxt_set_xdp_tx_rings(bp);
+ bnxt_set_cp_rings(bp, true);
+ }
}
static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
@@ -16588,16 +16592,17 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
rc = __bnxt_reserve_rings(bp);
if (rc && rc != -ENODEV)
netdev_warn(bp->dev, "Unable to reserve tx rings\n");
- bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+
+ bnxt_adj_tx_rings(bp);
if (sh)
- bnxt_trim_dflt_sh_rings(bp);
+ bnxt_adj_dflt_rings(bp, true);
/* Rings may have been trimmed, re-reserve the trimmed rings. */
if (bnxt_need_reserve_rings(bp)) {
rc = __bnxt_reserve_rings(bp);
if (rc && rc != -ENODEV)
netdev_warn(bp->dev, "2nd rings reservation failed.\n");
- bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+ bnxt_adj_tx_rings(bp);
}
if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
bp->rx_nr_rings++;
@@ -16631,7 +16636,7 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp)
if (rc)
goto init_dflt_ring_err;
- bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+ bnxt_adj_tx_rings(bp);
bnxt_set_dflt_rfs(bp);
--
2.51.0
^ permalink raw reply related
* [PATCH net 1/3] bnxt_en: Refactor some basic ring setup and adjustment logic
From: Michael Chan @ 2026-03-29 23:25 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, kuba, pabeni, andrew+netdev, pavan.chebbi,
andrew.gospodarek, Kalesh AP
In-Reply-To: <20260329232528.870637-1-michael.chan@broadcom.com>
Refactor out the basic code that trims the default rings, sets up and
adjusts XDP TX rings and CP rings. There is no change in behavior.
This is to prepare for the next bug fix patch.
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 53 +++++++++++++------
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 +
.../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 5 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 5 +-
4 files changed, 41 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 0751c0e4581a..fa44c86af67b 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -12992,6 +12992,21 @@ static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp)
return bp->num_tc ? bp->tx_nr_rings / bp->num_tc : bp->tx_nr_rings;
}
+static void bnxt_set_xdp_tx_rings(struct bnxt *bp)
+{
+ bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
+ bp->tx_nr_rings += bp->tx_nr_rings_xdp;
+}
+
+static void bnxt_adj_tx_rings(struct bnxt *bp)
+{
+ /* Make adjustments if reserved TX rings are less than requested */
+ bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
+ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+ if (bp->tx_nr_rings_xdp)
+ bnxt_set_xdp_tx_rings(bp);
+}
+
static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
{
int rc = 0;
@@ -13009,13 +13024,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
if (rc)
return rc;
- /* Make adjustments if reserved TX rings are less than requested */
- bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
- bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
- if (bp->tx_nr_rings_xdp) {
- bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
- bp->tx_nr_rings += bp->tx_nr_rings_xdp;
- }
+ bnxt_adj_tx_rings(bp);
rc = bnxt_alloc_mem(bp, irq_re_init);
if (rc) {
netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
@@ -15436,11 +15445,19 @@ static int bnxt_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
+void bnxt_set_cp_rings(struct bnxt *bp, bool sh)
+{
+ int tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
+
+ bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
+ tx_cp + bp->rx_nr_rings;
+}
+
int bnxt_setup_mq_tc(struct net_device *dev, u8 tc)
{
struct bnxt *bp = netdev_priv(dev);
bool sh = false;
- int rc, tx_cp;
+ int rc;
if (tc > bp->max_tc) {
netdev_err(dev, "Too many traffic classes requested: %d. Max supported is %d.\n",
@@ -15473,9 +15490,7 @@ int bnxt_setup_mq_tc(struct net_device *dev, u8 tc)
bp->num_tc = 0;
}
bp->tx_nr_rings += bp->tx_nr_rings_xdp;
- tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
- bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
- tx_cp + bp->rx_nr_rings;
+ bnxt_set_cp_rings(bp, sh);
if (netif_running(bp->dev))
return bnxt_open_nic(bp, true, false);
@@ -16525,6 +16540,15 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp)
bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
}
+static void bnxt_adj_dflt_rings(struct bnxt *bp, bool sh)
+{
+ if (sh)
+ bnxt_trim_dflt_sh_rings(bp);
+ else
+ bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
+ bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+}
+
static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
{
int dflt_rings, max_rx_rings, max_tx_rings, rc;
@@ -16550,11 +16574,8 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
return rc;
bp->rx_nr_rings = min_t(int, dflt_rings, max_rx_rings);
bp->tx_nr_rings_per_tc = min_t(int, dflt_rings, max_tx_rings);
- if (sh)
- bnxt_trim_dflt_sh_rings(bp);
- else
- bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
- bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+
+ bnxt_adj_dflt_rings(bp, sh);
avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings;
if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) {
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index a97d651130df..4bc7f7aeaab3 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -2985,6 +2985,7 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
int tx_xdp);
int bnxt_fw_init_one(struct bnxt *bp);
bool bnxt_hwrm_reset_permitted(struct bnxt *bp);
+void bnxt_set_cp_rings(struct bnxt *bp, bool sh);
int bnxt_setup_mq_tc(struct net_device *dev, u8 tc);
struct bnxt_ntuple_filter *bnxt_lookup_ntp_filter_from_idx(struct bnxt *bp,
struct bnxt_ntuple_filter *fltr, u32 idx);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index 28d0ece2e7b1..0407aa1b3190 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -945,7 +945,6 @@ static int bnxt_set_channels(struct net_device *dev,
bool sh = false;
int tx_xdp = 0;
int rc = 0;
- int tx_cp;
if (channel->other_count)
return -EINVAL;
@@ -1013,9 +1012,7 @@ static int bnxt_set_channels(struct net_device *dev,
if (tcs > 1)
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tcs + tx_xdp;
- tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
- bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
- tx_cp + bp->rx_nr_rings;
+ bnxt_set_cp_rings(bp, sh);
/* After changing number of rx channels, update NTUPLE feature. */
netdev_update_features(dev);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 85cbeb35681c..bebe37e139c9 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -384,7 +384,7 @@ int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
{
struct net_device *dev = bp->dev;
- int tx_xdp = 0, tx_cp, rc, tc;
+ int tx_xdp = 0, rc, tc;
struct bpf_prog *old;
netdev_assert_locked(dev);
@@ -431,8 +431,7 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
}
bp->tx_nr_rings_xdp = tx_xdp;
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc + tx_xdp;
- tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
- bp->cp_nr_rings = max_t(int, tx_cp, bp->rx_nr_rings);
+ bnxt_set_cp_rings(bp, true);
bnxt_set_tpa_flags(bp);
bnxt_set_ring_params(bp);
--
2.51.0
^ permalink raw reply related
* [PATCH net 0/3] bnxt_en: Bug fixes
From: Michael Chan @ 2026-03-29 23:25 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, kuba, pabeni, andrew+netdev, pavan.chebbi,
andrew.gospodarek
The first patch is a refactor patch needed by the second patch to
fix XDP ring initialization during FW reset. The third patch
fixes an issue related to stats context reservation for RoCE.
Michael Chan (2):
bnxt_en: Refactor some basic ring setup and adjustment logic
bnxt_en: Don't assume XDP is never enabled in
bnxt_init_dflt_ring_mode()
Pavan Chebbi (1):
bnxt_en: Restore default stat ctxs for ULP when resource is available
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 68 +++++++++++++------
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 +
.../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 5 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 5 +-
4 files changed, 52 insertions(+), 27 deletions(-)
--
2.51.0
^ permalink raw reply
* [PATCH 2/2] net: phy: microchip: enable downshift by default on LAN88xx
From: Nicolai Buchwitz @ 2026-03-29 22:42 UTC (permalink / raw)
To: netdev
Cc: Phil Elwell, Nicolai Buchwitz, Andrew Lunn, Heiner Kallweit,
Russell King, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, linux-kernel
In-Reply-To: <20260329224202.500229-1-nb@tipi-net.de>
Enable auto-downshift from 1000BASE-T to 100BASE-TX after 2 failed
auto-negotiation attempts by default. This ensures that links with
faulty or missing cable pairs (C and D) fall back to 100Mbps without
requiring userspace configuration.
Users can override or disable downshift at runtime:
ethtool --set-phy-tunable eth0 downshift off
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
---
drivers/net/phy/microchip.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c
index a044be1ade79..3455fe713088 100644
--- a/drivers/net/phy/microchip.c
+++ b/drivers/net/phy/microchip.c
@@ -371,7 +371,7 @@ static void lan88xx_set_mdix(struct phy_device *phydev)
static int lan88xx_config_init(struct phy_device *phydev)
{
- int val;
+ int val, err;
/*Zerodetect delay enable */
val = phy_read_mmd(phydev, MDIO_MMD_PCS,
@@ -384,6 +384,11 @@ static int lan88xx_config_init(struct phy_device *phydev)
/* Config DSP registers */
lan88xx_config_TR_regs(phydev);
+ /* Enable downshift after 2 failed attempts by default */
+ err = lan88xx_set_downshift(phydev, 2);
+ if (err < 0)
+ return err;
+
return 0;
}
--
2.51.0
^ permalink raw reply related
* [PATCH 1/2] net: phy: microchip: add downshift tunable support for LAN88xx
From: Nicolai Buchwitz @ 2026-03-29 22:41 UTC (permalink / raw)
To: netdev
Cc: Phil Elwell, Nicolai Buchwitz, Andrew Lunn, Heiner Kallweit,
Russell King, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, linux-kernel
In-Reply-To: <20260329224202.500229-1-nb@tipi-net.de>
Implement the standard ETHTOOL_PHY_DOWNSHIFT tunable for the LAN88xx
PHY. This allows runtime configuration of the auto-downshift feature
via ethtool:
ethtool --set-phy-tunable eth0 downshift on count 3
The LAN88xx PHY supports downshifting from 1000BASE-T to 100BASE-TX
after 2-5 failed auto-negotiation attempts. Valid count values are
2, 3, 4 and 5.
This is based on an earlier downstream implementation by Phil Elwell.
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
---
drivers/net/phy/microchip.c | 89 ++++++++++++++++++++++++++++++++++++
include/linux/microchipphy.h | 9 ++++
2 files changed, 98 insertions(+)
diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c
index dc8634e7bcbe..a044be1ade79 100644
--- a/drivers/net/phy/microchip.c
+++ b/drivers/net/phy/microchip.c
@@ -193,6 +193,93 @@ static void lan88xx_config_TR_regs(struct phy_device *phydev)
phydev_warn(phydev, "Failed to Set Register[0x1686]\n");
}
+static int lan88xx_get_downshift(struct phy_device *phydev, u8 *data)
+{
+ int val;
+
+ val = phy_read_paged(phydev, 1, LAN78XX_PHY_CTRL3);
+ if (val < 0)
+ return val;
+
+ if (!(val & LAN78XX_PHY_CTRL3_AUTO_DOWNSHIFT)) {
+ *data = DOWNSHIFT_DEV_DISABLE;
+ return 0;
+ }
+
+ switch (val & LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_MASK) {
+ case LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_2:
+ *data = 2;
+ break;
+ case LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_3:
+ *data = 3;
+ break;
+ case LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_4:
+ *data = 4;
+ break;
+ case LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_5:
+ *data = 5;
+ break;
+ }
+
+ return 0;
+}
+
+static int lan88xx_set_downshift(struct phy_device *phydev, u8 cnt)
+{
+ u32 mask = LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_MASK |
+ LAN78XX_PHY_CTRL3_AUTO_DOWNSHIFT;
+ u32 val;
+
+ if (cnt == DOWNSHIFT_DEV_DISABLE)
+ return phy_modify_paged(phydev, 1, LAN78XX_PHY_CTRL3,
+ LAN78XX_PHY_CTRL3_AUTO_DOWNSHIFT, 0);
+
+ if (cnt == DOWNSHIFT_DEV_DEFAULT_COUNT)
+ cnt = 2;
+
+ switch (cnt) {
+ case 2:
+ val = LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_2;
+ break;
+ case 3:
+ val = LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_3;
+ break;
+ case 4:
+ val = LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_4;
+ break;
+ case 5:
+ val = LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_5;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return phy_modify_paged(phydev, 1, LAN78XX_PHY_CTRL3, mask,
+ val | LAN78XX_PHY_CTRL3_AUTO_DOWNSHIFT);
+}
+
+static int lan88xx_get_tunable(struct phy_device *phydev,
+ struct ethtool_tunable *tuna, void *data)
+{
+ switch (tuna->id) {
+ case ETHTOOL_PHY_DOWNSHIFT:
+ return lan88xx_get_downshift(phydev, data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int lan88xx_set_tunable(struct phy_device *phydev,
+ struct ethtool_tunable *tuna, const void *data)
+{
+ switch (tuna->id) {
+ case ETHTOOL_PHY_DOWNSHIFT:
+ return lan88xx_set_downshift(phydev, *(const u8 *)data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static int lan88xx_probe(struct phy_device *phydev)
{
struct device *dev = &phydev->mdio.dev;
@@ -499,6 +586,8 @@ static struct phy_driver microchip_phy_driver[] = {
.set_wol = lan88xx_set_wol,
.read_page = lan88xx_read_page,
.write_page = lan88xx_write_page,
+ .get_tunable = lan88xx_get_tunable,
+ .set_tunable = lan88xx_set_tunable,
},
{
PHY_ID_MATCH_MODEL(PHY_ID_LAN937X_TX),
diff --git a/include/linux/microchipphy.h b/include/linux/microchipphy.h
index 517288da19fd..a8deae3977e9 100644
--- a/include/linux/microchipphy.h
+++ b/include/linux/microchipphy.h
@@ -61,6 +61,15 @@
/* Registers specific to the LAN7800/LAN7850 embedded phy */
#define LAN78XX_PHY_LED_MODE_SELECT (0x1D)
+/* PHY Control 3 register (page 1) */
+#define LAN78XX_PHY_CTRL3 (0x14)
+#define LAN78XX_PHY_CTRL3_AUTO_DOWNSHIFT BIT(4)
+#define LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_MASK GENMASK(3, 2)
+#define LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_2 (0 << 2)
+#define LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_3 (1 << 2)
+#define LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_4 (2 << 2)
+#define LAN78XX_PHY_CTRL3_DOWNSHIFT_CTRL_5 (3 << 2)
+
/* DSP registers */
#define PHY_ARDENNES_MMD_DEV_3_PHY_CFG (0x806A)
#define PHY_ARDENNES_MMD_DEV_3_PHY_CFG_ZD_DLY_EN_ (0x2000)
--
2.51.0
^ permalink raw reply related
* [PATCH net-next 0/2] net: phy: microchip: add downshift support for LAN88xx
From: Nicolai Buchwitz @ 2026-03-29 22:41 UTC (permalink / raw)
To: netdev; +Cc: Phil Elwell, Nicolai Buchwitz
Add standard ETHTOOL_PHY_DOWNSHIFT tunable support for the Microchip
LAN88xx PHY, following the same pattern used by Marvell and other PHY
drivers.
Ethernet cables with faulty or missing pairs (specifically C and D)
can successfully auto-negotiate 1000BASE-T but fail to establish a
stable link. The LAN88xx PHY supports automatic downshift to
100BASE-TX after a configurable number of failed attempts (2-5).
Patch 1 adds the get/set tunable implementation.
Patch 2 enables downshift by default with a count of 2.
Based on an earlier downstream implementation by Phil Elwell.
Tested on Raspberry Pi 3B+ (LAN7515/LAN88xx).
Nicolai Buchwitz (2):
net: phy: microchip: add downshift tunable support for LAN88xx
net: phy: microchip: enable downshift by default on LAN88xx
drivers/net/phy/microchip.c | 96 +++++++++++++++++++++++++++++++++++-
include/linux/microchipphy.h | 9 ++++
2 files changed, 104 insertions(+), 1 deletion(-)
--
2.51.0
^ permalink raw reply
* Re: [net-next v6 12/12] selftests: drv-net: Add USO test
From: Jakub Kicinski @ 2026-03-29 22:31 UTC (permalink / raw)
To: Joe Damato
Cc: netdev, Shuah Khan, andrew+netdev, davem, edumazet, pabeni, horms,
michael.chan, pavan.chebbi, linux-kernel, leon, linux-kselftest
In-Reply-To: <20260326235238.2940471-13-joe@dama.to>
On Thu, 26 Mar 2026 16:52:31 -0700 Joe Damato wrote:
> Add a simple test for USO. Can be used with netdevsim or real hardware.
> Tests both ipv4 and ipv6 with several full segments and a partial
> segment.
> +def _test_uso(cfg, ipver, mss, total_payload):
> + cfg.require_ipver(ipver)
> +
> + try:
> + ethtool(f"-K {cfg.ifname} tx-udp-segmentation on")
> + except Exception as exc:
> + raise KsftSkipEx(
> + "Device does not support tx-udp-segmentation") from exc
> + defer(ethtool, f"-K {cfg.ifname} tx-udp-segmentation off")
If may have been on already when we started, no?
> + expected_segs = (total_payload + mss - 1) // mss
> +
> + rx_before = _get_rx_packets(cfg)
Let's run a little program on the remote that receives the packets
and validates they were correct? Maybe socat can do?
> + port = rand_port(stype=socket.SOCK_DGRAM)
> + _send_uso(cfg, ipver, mss, total_payload, port)
> +
> + time.sleep(0.5)
What's this? Did you mean to wait for stats to settle?
cfg.wait_hw_stats_settle()
> + rx_after = _get_rx_packets(cfg)
> + rx_delta = rx_after - rx_before
Instead of checking Rx (which is probably fine) we may want to check Tx
has the right number of frames. Sender may have mis-counted the whole
USO as one packet if it's buggy?
> + ksft_ge(rx_delta, expected_segs,
> + comment=f"Expected >= {expected_segs} rx packets, got {rx_delta}")
> +
> +
> +def test_uso_v4(cfg):
> + """USO IPv4: 11 segments (10 full + 1 partial)."""
> + _test_uso(cfg, "4", 1400, 1400 * 10 + 500)
> +
> +
> +def test_uso_v6(cfg):
> + """USO IPv6: 11 segments (10 full + 1 partial)."""
> + _test_uso(cfg, "6", 1400, 1400 * 10 + 500)
> +
> +
> +def test_uso_v4_exact(cfg):
> + """USO IPv4: exact multiple of MSS (5 full segments)."""
> + _test_uso(cfg, "4", 1400, 1400 * 5)
Variants are probably a good fit here.
^ permalink raw reply
* Re: [net-next v6 11/12] net: netdevsim: Add support for SW USO
From: Jakub Kicinski @ 2026-03-29 22:26 UTC (permalink / raw)
To: Joe Damato
Cc: netdev, David S. Miller, Eric Dumazet, Paolo Abeni, andrew+netdev,
horms, michael.chan, pavan.chebbi, linux-kernel, leon
In-Reply-To: <20260326235238.2940471-12-joe@dama.to>
On Thu, 26 Mar 2026 16:52:30 -0700 Joe Damato wrote:
> Add support for UDP Segmentation Offloading in software (SW USO). This
> is helpful for testing when real hardware is not available. A test which
> uses this codepath will be added in a following commit.
Not sure we need to carry this in the tree.
We have a bnxt device in NIPA, the code will be exercised.
^ permalink raw reply
* Re: [net-next v6 09/12] net: bnxt: Add SW GSO completion and teardown support
From: Jakub Kicinski @ 2026-03-29 22:22 UTC (permalink / raw)
To: Joe Damato
Cc: netdev, Michael Chan, David S. Miller, Eric Dumazet, Paolo Abeni,
andrew+netdev, horms, pavan.chebbi, linux-kernel, leon
In-Reply-To: <20260326235238.2940471-10-joe@dama.to>
On Thu, 26 Mar 2026 16:52:28 -0700 Joe Damato wrote:
> + if (head_buf->is_sw_gso == BNXT_SW_GSO_LAST) {
> + if (dma_use_iova(&head_buf->iova_state))
> + dma_iova_destroy(&pdev->dev,
> + &head_buf->iova_state,
> + head_buf->iova_total_len,
> + DMA_TO_DEVICE, 0);
Do we have to expose the dma_use_iova() stuff to the driver at all?
Could we have a function the driver is supposed to call to clean up,
always, and what the function does is up to the TSO lib?
^ permalink raw reply
* Re: [net-next v6 08/12] net: bnxt: Implement software USO
From: Jakub Kicinski @ 2026-03-29 22:20 UTC (permalink / raw)
To: Joe Damato
Cc: netdev, Michael Chan, David S. Miller, Eric Dumazet, Paolo Abeni,
andrew+netdev, horms, pavan.chebbi, linux-kernel, leon
In-Reply-To: <20260326235238.2940471-9-joe@dama.to>
On Thu, 26 Mar 2026 16:52:27 -0700 Joe Damato wrote:
> + /* Upper bound on the number of descriptors needed.
> + *
> + * Each segment uses 1 long BD + 1 ext BD + payload BDs, which is
> + * at most num_segs + nr_frags (each frag boundary crossing adds at
> + * most 1 extra BD).
> + */
> + bds_needed = 3 * num_segs + skb_shinfo(skb)->nr_frags + 1;
> +
> + if (unlikely(bnxt_tx_avail(bp, txr) < bds_needed)) {
> + netif_txq_try_stop(txq, bnxt_tx_avail(bp, txr),
> + bp->tx_wake_thresh);
> + return NETDEV_TX_BUSY;
> + }
> +
> + slots = BNXT_SW_USO_MAX_SEGS - (txr->tx_inline_prod - txr->tx_inline_cons);
> +
> + if (unlikely(slots < num_segs)) {
> + netif_txq_try_stop(txq, bnxt_tx_avail(bp, txr),
This looks sus, try_stop() will evaluate the bnxt_tx_avail(bp, txr)
and leave the ring running.
> + bp->tx_wake_thresh);
Is tx_wake_thresh larger than the max USO even for smallest ring size?
^ permalink raw reply
* Re: [net-next v6 07/12] net: bnxt: Add boilerplate GSO code
From: Jakub Kicinski @ 2026-03-29 22:12 UTC (permalink / raw)
To: Joe Damato
Cc: netdev, Michael Chan, David S. Miller, Eric Dumazet, Paolo Abeni,
Richard Cochran, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, andrew+netdev, horms,
pavan.chebbi, linux-kernel, leon, bpf
In-Reply-To: <20260326235238.2940471-8-joe@dama.to>
On Thu, 26 Mar 2026 16:52:26 -0700 Joe Damato wrote:
> @@ -891,6 +891,7 @@ struct bnxt_sw_tx_bd {
> u8 is_ts_pkt;
> u8 is_push;
> u8 action;
> + u8 is_sw_gso;
> unsigned short nr_frags;
nit: maybe group the is_* together, IOW move new fields before @action?
^ permalink raw reply
* Re: [net-next v6 01/12] net: tso: Introduce tso_dma_map
From: Jakub Kicinski @ 2026-03-29 22:11 UTC (permalink / raw)
To: Joe Damato
Cc: netdev, David S. Miller, Eric Dumazet, Paolo Abeni, andrew+netdev,
horms, michael.chan, pavan.chebbi, linux-kernel, leon
In-Reply-To: <20260326235238.2940471-2-joe@dama.to>
On Thu, 26 Mar 2026 16:52:20 -0700 Joe Damato wrote:
> Add struct tso_dma_map to tso.h for tracking DMA addresses of mapped
> GSO payload data.
>
> The struct combines DMA mapping storage with iterator state, allowing
> drivers to walk pre-mapped DMA regions linearly. Includes fields for
> the DMA IOVA path (iova_state, iova_offset, total_len) and a fallback
> per-region path (linear_dma, frags[], frag_idx, offset).
>
> Helpers to initialize and operate on this struct will be added in the
> next commit.
Let's squash this with patch 2? Quite useful to see the struct when
reviewing the code..
^ permalink raw reply
* [PATCH net-next] net: airoha: Fix typo in airoha_set_gdm2_loopback routine name
From: Lorenzo Bianconi @ 2026-03-29 22:03 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: linux-arm-kernel, linux-mediatek, netdev, Lorenzo Bianconi
Rename airhoha_set_gdm2_loopback() in airoha_set_gdm2_loopback()
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 82e53c60f561f6314fbf201ba8bc8711e40edc68..2beba017e791d20f142e754edafcd402d8cc496f 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1709,7 +1709,7 @@ static int airoha_dev_set_macaddr(struct net_device *dev, void *p)
return 0;
}
-static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
+static int airoha_set_gdm2_loopback(struct airoha_gdm_port *port)
{
struct airoha_eth *eth = port->qdma->eth;
u32 val, pse_port, chan, nbq;
@@ -1785,7 +1785,7 @@ static int airoha_dev_init(struct net_device *dev)
if (!eth->ports[1]) {
int err;
- err = airhoha_set_gdm2_loopback(port);
+ err = airoha_set_gdm2_loopback(port);
if (err)
return err;
}
---
base-commit: cf0d9080c6f795bc6be08babbffa29b62c06e9b0
change-id: 20260329-airoha_set_gdm2_loopback-fix-typo-ce5131054f56
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply related
* Re: [PATCH net-next v2 0/2] net: hsr: subsystem cleanups and modernization
From: patchwork-bot+netdevbpf @ 2026-03-29 21:40 UTC (permalink / raw)
To: Luka Gejak
Cc: davem, edumazet, kuba, pabeni, netdev, horms, fmaurer, liuhangbin,
linux-kernel
In-Reply-To: <20260326174600.136232-1-luka.gejak@linux.dev>
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 26 Mar 2026 18:45:58 +0100 you wrote:
> From: Luka Gejak <luka.gejak@linux.dev>
>
> Changes in v2:
> - dropped trivial cleanup-only patches per netdev clean-up policy
> - added AI attribution for cover-letter/commit-message wording only
> - dropped fallthrough/BIT conversion patches per review
>
> [...]
Here is the summary with links:
- [net-next,v2,1/2] net: hsr: constify hsr_ops and prp_ops protocol operation structures
https://git.kernel.org/netdev/net-next/c/3e09b370f830
- [net-next,v2,2/2] net: hsr: use __func__ instead of hardcoded function name
https://git.kernel.org/netdev/net-next/c/137ac69c15fd
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next v5 00/14] macb usrio/tsu patches
From: patchwork-bot+netdevbpf @ 2026-03-29 21:40 UTC (permalink / raw)
To: Conor Dooley
Cc: netdev, conor.dooley, Valentina.FernandezAlanis, andrew+netdev,
davem, edumazet, kuba, pabeni, robh, krzk+dt, conor+dt,
daire.mcnamara, pjw, palmer, aou, alex, nicolas.ferre,
claudiu.beznea, richardcochran, samuel.holland, devicetree,
linux-kernel, linux-riscv, dave.stevenson, sean.anderson,
vineeth.karumanchi, abin.joseph, theo.lebrun, Ryan.Wanner,
haokexin
In-Reply-To: <20260325-unsterile-flail-4c7729750dc4@spud>
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Wed, 25 Mar 2026 16:28:04 +0000 you wrote:
> From: Conor Dooley <conor.dooley@microchip.com>
>
> Hey folks,
>
> At the very least, it'd be good of the soc vendor folks could check
> their platforms and see if their usrio stuff actually lines up with what
> the driver currently calls "macb_default_usrio". Ours didn't and it was
> a nasty surprise.
>
> [...]
Here is the summary with links:
- [net-next,v5,01/14] Revert "net: macb: Clean up the .usrio settings in macb_config instances"
https://git.kernel.org/netdev/net-next/c/8ccf062c6770
- [net-next,v5,02/14] net: macb: rename macb_default_usrio to at91_default_usrio as not all platforms have mii mode control in usrio
https://git.kernel.org/netdev/net-next/c/a17871778ee2
- [net-next,v5,03/14] net: macb: split USRIO_HAS_CLKEN capability in two
https://git.kernel.org/netdev/net-next/c/039f185a0060
- [net-next,v5,04/14] dt-bindings: net: cdns,macb: replace cdns,refclk-ext with cdns,refclk-source
https://git.kernel.org/netdev/net-next/c/dfa36d7e860c
- [net-next,v5,05/14] net: macb: rework usrio refclk selection code
https://git.kernel.org/netdev/net-next/c/6c5b565d7d41
- [net-next,v5,06/14] net: macb: np4 doesn't need a usrio pointer
https://git.kernel.org/netdev/net-next/c/826cbe636e10
- [net-next,v5,07/14] net: macb: add mpfs specific usrio configuration
https://git.kernel.org/netdev/net-next/c/c711311d6ba3
- [net-next,v5,08/14] net: macb: warn on pclk use as a tsu_clk fallback
https://git.kernel.org/netdev/net-next/c/3fe13d858f83
- [net-next,v5,09/14] net: macb: clean up tsu clk rate acquisition
https://git.kernel.org/netdev/net-next/c/b698a1e397ab
- [net-next,v5,10/14] dt-bindings: net: macb: add property indicating timer adjust mode
https://git.kernel.org/netdev/net-next/c/09a6164a4f1d
- [net-next,v5,11/14] net: macb: timer adjust mode is not supported
https://git.kernel.org/netdev/net-next/c/41adda8764fd
- [net-next,v5,12/14] net: macb: runtime detect MACB_CAPS_USRIO_DISABLED
https://git.kernel.org/netdev/net-next/c/47c86c463612
- [net-next,v5,13/14] net: macb: set MACB_CAPS_USRIO_DISABLED if no usrio config is provided
https://git.kernel.org/netdev/net-next/c/32fc6a9f6e75
- [net-next,v5,14/14] net: macb: drop usrio pointer on EyeQ5 config
https://git.kernel.org/netdev/net-next/c/cd1082a96f9a
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH] net: wan/fsl_ucc_hdlc: cleanup ucc_hdlc_poll
From: patchwork-bot+netdevbpf @ 2026-03-29 21:30 UTC (permalink / raw)
To: Tomas Alvarez Vanoli; +Cc: netdev, linuxppc-dev, qiang.zhao, andrew+netdev
In-Reply-To: <20260326100232.904289-1-tomas.alvarez-vanoli@hitachienergy.com>
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 26 Mar 2026 11:02:32 +0100 you wrote:
> Immediately after setting to 0 we are adding to it, and subtracting 0
> from budget. Replace with just assignment and no subtraction.
>
> Signed-off-by: Tomas Alvarez Vanoli <tomas.alvarez-vanoli@hitachienergy.com>
> ---
> drivers/net/wan/fsl_ucc_hdlc.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
Here is the summary with links:
- net: wan/fsl_ucc_hdlc: cleanup ucc_hdlc_poll
https://git.kernel.org/netdev/net-next/c/57ec1622b62a
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next v5 0/6] bnxt_en: Add XDP RSS hash metadata support
From: patchwork-bot+netdevbpf @ 2026-03-29 21:20 UTC (permalink / raw)
To: Chris J Arges
Cc: netdev, michael.chan, pavan.chebbi, davem, joe, gospo, kuba,
pabeni, edumazet, andrew+netdev, horms, ast, daniel, hawk,
john.fastabend, sdf, shuah, bpf, linux-kselftest, kernel-team
In-Reply-To: <20260325201139.2501937-1-carges@cloudflare.com>
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Wed, 25 Mar 2026 15:09:46 -0500 you wrote:
> This series adds XDP RSS hash metadata extraction support for the bnxt_en
> driver and includes selftests to validate the functionality. I was able
> to test this on a BCM57414 NIC.
>
> Patches 1-4 implement the driver support:
> - Patch 1 adds bnxt_xdp_buff to wrap xdp_buff with
> pointers to the hardware RX completion descriptors and the
> completion type. This is similar to other driver implementations.
> - Patch 2 adds xmo_rx_hash callback for CMP_TYPE_RX_L2_CMP completions.
> - Patch 3 moves bnxt_rss_ext_op to bnxt.h
> - Patch 4 adds handling for CMP_TYPE_RX_L2_V3_CMP completions
>
> [...]
Here is the summary with links:
- [net-next,v5,1/6] bnxt_en: use bnxt_xdp_buff for xdp context
https://git.kernel.org/netdev/net-next/c/542d3ec4508f
- [net-next,v5,2/6] bnxt_en: Implement XDP RSS hash metadata extraction
https://git.kernel.org/netdev/net-next/c/e5648b08cbfc
- [net-next,v5,3/6] bnxt_en: Move bnxt_rss_ext_op into header
https://git.kernel.org/netdev/net-next/c/4a037aeb6bc8
- [net-next,v5,4/6] bnxt_en: Implement XDP RSS hash metadata extraction for V3_CMP
https://git.kernel.org/netdev/net-next/c/5ec22d5f2afc
- [net-next,v5,5/6] selftests: net: move common xdp.py functions into lib
https://git.kernel.org/netdev/net-next/c/4ce06406958b
- [net-next,v5,6/6] selftests: drv-net: xdp: Add rss_hash metadata tests
https://git.kernel.org/netdev/net-next/c/e3cdf6cf5fc6
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next v2 3/3] gve: implement PTP gettimex64
From: Jakub Kicinski @ 2026-03-29 21:20 UTC (permalink / raw)
To: hramamurthy
Cc: Jakub Kicinski, netdev, joshwash, andrew+netdev, davem, edumazet,
pabeni, richardcochran, willemb, nktgrg, jfraker, ziweixiao,
maolson, thostet, jordanrhee, jefrogers, alok.a.tiwari, yyd,
linux-kernel, namangulati
In-Reply-To: <20260326224527.1044097-4-hramamurthy@google.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
Subject: gve: implement PTP gettimex64
This commit implements the PTP gettimex64 function to enable chrony and
phc2sys to synchronize the system clock to the NIC clock. It reads the
NIC timestamp along with pre and post system cycle counters to minimize
the uncertainty window.
> diff --git a/drivers/net/ethernet/google/gve/gve_ptp.c b/drivers/net/ethernet/google/gve/gve_ptp.c
> index 140b8fbce4f4..bea794541f30 100644
> --- a/drivers/net/ethernet/google/gve/gve_ptp.c
> +++ b/drivers/net/ethernet/google/gve/gve_ptp.c
> @@ -10,28 +10,203 @@
[ ... ]
> +static int gve_adminq_read_timestamp(struct gve_priv *priv,
> + cycles_t *pre_cycles,
> + cycles_t *post_cycles)
> +{
> + unsigned long delay_us = 1000;
> + int retry_count = 0;
> + int err;
> +
> + lockdep_assert_held(&priv->nic_ts_read_lock);
> +
> + do {
> + *pre_cycles = get_cycles();
> + err = gve_adminq_report_nic_ts(priv, priv->nic_ts_report_bus);
> +
> + /* Ensure cycle counter is sampled after AdminQ cmd returns */
> + rmb();
> + *post_cycles = get_cycles();
Are execution barriers needed around get_cycles() here? rmb() orders
memory accesses, but the CPU might still speculatively execute the cycle
counter reads out of order with respect to the AdminQ commands.
Could this speculative reordering cause the strict bounds validation in
gve_ptp_gettimex64() to fail spuriously?
[ ... ]
> static int gve_ptp_gettimex64(struct ptp_clock_info *info,
> struct timespec64 *ts,
> struct ptp_system_timestamp *sts)
> {
> - return -EOPNOTSUPP;
> + struct gve_ptp *ptp = container_of(info, struct gve_ptp, info);
> + struct gve_sysclock_sample sysclock = {0};
> + struct gve_priv *priv = ptp->priv;
> + struct system_time_snapshot snap;
> + u64 nic_ts;
> + int err;
> +
> + /* Take system clock snapshot before sampling cycle counters */
> + if (sts)
> + ktime_get_snapshot(&snap);
> +
> + err = gve_clock_nic_ts_read(priv, &nic_ts, &sysclock);
Could the system time snapshot become stale here?
If priv->nic_ts_read_lock is contended, or if gve_adminq_read_timestamp()
retries and sleeps, the snapshot might be taken significantly before the
actual hardware read.
Would it be more accurate to take the snapshot immediately before reading the
hardware, inside the mutex?
> + if (err)
> + return err;
> +
> + if (sts) {
> + /* Reject samples with out of order system clock values */
> + if (!(sysclock.host_pre_cycles <= sysclock.nic_pre_cycles &&
> + sysclock.nic_pre_cycles <= sysclock.nic_post_cycles &&
> + sysclock.nic_post_cycles <= sysclock.host_post_cycles)) {
> + dev_err_ratelimited(&priv->pdev->dev,
> + "AdminQ system clock cycle counts out of order. Expecting %llu <= %llu <= %llu <= %llu\n",
> + (u64)sysclock.host_pre_cycles,
> + sysclock.nic_pre_cycles,
> + sysclock.nic_post_cycles,
> + (u64)sysclock.host_post_cycles);
> + return -EBADMSG;
How does this behave on architectures where get_cycles() is not implemented
and returns 0, or with older firmware that leaves nic_pre_cycles and
nic_post_cycles as 0?
It looks like the bounds check would unconditionally fail and return -EBADMSG.
Since userspace tools like chrony usually expect -EOPNOTSUPP for unsupported
extended ioctls to fall back to basic PTP ioctls, will returning -EBADMSG
cause a hard failure for clock synchronization?
[ ... ]
> @@ -132,7 +307,7 @@ int gve_init_clock(struct gve_priv *priv)
> goto release_ptp;
> }
> mutex_init(&priv->nic_ts_read_lock);
> - err = gve_clock_nic_ts_read(priv, &nic_raw);
> + err = gve_clock_nic_ts_read(priv, &nic_raw, NULL);
> if (err) {
> dev_err(&priv->pdev->dev, "failed to read NIC clock %d\n", err);
> goto release_nic_ts_report;
Is there a race condition exposing the PTP device to userspace before its
resources are fully initialized?
Looking at gve_init_clock(), gve_ptp_init() is called before allocating
nic_ts_report and initializing nic_ts_read_lock:
err = gve_ptp_init(priv);
if (err)
return err;
priv->nic_ts_report = dma_alloc_coherent(...);
...
mutex_init(&priv->nic_ts_read_lock);
If a concurrent userspace process immediately invokes the
PTP_SYS_OFFSET_EXTENDED ioctl after gve_ptp_init() registers the /dev/ptpX
device, could it call gve_ptp_gettimex64() and attempt to lock the
uninitialized mutex or dereference the NULL nic_ts_report pointer?
Additionally, in the error path for gve_init_clock():
release_nic_ts_report:
mutex_destroy(&priv->nic_ts_read_lock);
dma_free_coherent(...);
priv->nic_ts_report = NULL;
release_ptp:
gve_ptp_release(priv);
Could destroying the mutex and freeing the memory before gve_ptp_release()
create a use-after-free window if an ioctl is currently running?
^ permalink raw reply
* Re: [PATCH net-next v2 2/3] gve: make nic clock reads thread safe
From: Jakub Kicinski @ 2026-03-29 21:19 UTC (permalink / raw)
To: hramamurthy
Cc: Jakub Kicinski, netdev, joshwash, andrew+netdev, davem, edumazet,
pabeni, richardcochran, willemb, nktgrg, jfraker, ziweixiao,
maolson, thostet, jordanrhee, jefrogers, alok.a.tiwari, yyd,
linux-kernel, namangulati
In-Reply-To: <20260326224527.1044097-3-hramamurthy@google.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
gve: make nic clock reads thread safe
This commit adds a mutex to protect the shared DMA buffer used for receiving
NIC timestamp reports. The lock is needed to synchronize the periodic worker
and the upcoming gettimex64 ioctl.
> diff --git a/drivers/net/ethernet/google/gve/gve_ptp.c b/drivers/net/ethernet/google/gve/gve_ptp.c
> index 06b1cf4a5efc..140b8fbce4f4 100644
> --- a/drivers/net/ethernet/google/gve/gve_ptp.c
> +++ b/drivers/net/ethernet/google/gve/gve_ptp.c
[ ... ]
> @@ -109,6 +114,7 @@ static void gve_ptp_release(struct gve_priv *priv)
>
> int gve_init_clock(struct gve_priv *priv)
> {
> + u64 nic_raw;
> int err;
>
> err = gve_ptp_init(priv);
[ ... ]
> @@ -125,17 +131,20 @@ int gve_init_clock(struct gve_priv *priv)
> err = -ENOMEM;
> goto release_ptp;
> }
> - err = gve_clock_nic_ts_read(priv);
> + mutex_init(&priv->nic_ts_read_lock);
> + err = gve_clock_nic_ts_read(priv, &nic_raw);
Could this lead to a race condition with userspace?
If gve_ptp_init() registers the PTP clock via ptp_clock_register(), the
device is exposed to userspace immediately. If a userspace process opens the
device and calls the gettimex64 ioctl before the mutex and DMA buffer are
initialized here, it could cause a NULL pointer dereference or operate on an
uninitialized mutex.
> if (err) {
> dev_err(&priv->pdev->dev, "failed to read NIC clock %d\n", err);
> goto release_nic_ts_report;
> }
> + WRITE_ONCE(priv->last_sync_nic_counter, nic_raw);
> ptp_schedule_worker(priv->ptp->clock,
> msecs_to_jiffies(GVE_NIC_TS_SYNC_INTERVAL_MS));
>
> return 0;
>
> release_nic_ts_report:
> + mutex_destroy(&priv->nic_ts_read_lock);
> dma_free_coherent(&priv->pdev->dev,
> sizeof(struct gve_nic_ts_report),
> priv->nic_ts_report, priv->nic_ts_report_bus);
Is it safe to destroy the mutex and free the DMA buffer before calling
gve_ptp_release() here?
If the PTP clock is already registered and exposed to userspace by
gve_ptp_init(), this error path frees resources while the clock is still
active. A concurrent userspace ioctl could access the destroyed mutex or
freed buffer before gve_ptp_release() unregisters the clock.
Should all resource allocation and initialization strictly precede
ptp_clock_register(), and the error path unregister the clock before tearing
down the resources?
--
pw-bot: cr
^ permalink raw reply
* Re: [net-next v36] mctp pcc: Implement MCTP over PCC Transport
From: Jakub Kicinski @ 2026-03-29 21:15 UTC (permalink / raw)
To: admiyo
Cc: Jakub Kicinski, davem, jk, Jonathan.Cameron, netdev, linux-kernel,
sudeep.holla, lihuisong, andrew+netdev, pabeni, matt, edumazet
In-Reply-To: <20260325194256.988853-1-admiyo@os.amperecomputing.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
For local reproduction steps see https://netdev-ai.bots.linux.dev/ai-local.html
---
mctp pcc: Implement MCTP over PCC Transport
This commit implements a network driver for the Management Component
Transport Protocol (MCTP) over Platform Communication Channel (PCC).
It creates MCTP network devices via ACPI that communicate through shared
memory and mailbox mechanisms.
Link: https://www.dmtf.org/sites/default/files/standards/documents/DSP0292_1.0.0WIP50.pdf
Link: https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/14_Platform_Communications_Channel/Platform_Comm_Channel.html
> diff --git a/drivers/net/mctp/Kconfig b/drivers/net/mctp/Kconfig
> index cf325ab0b1ef..77cd4091050c 100644
> --- a/drivers/net/mctp/Kconfig
> +++ b/drivers/net/mctp/Kconfig
> @@ -47,6 +47,19 @@ config MCTP_TRANSPORT_I3C
> A MCTP protocol network device is created for each I3C bus
> having a "mctp-controller" devicetree property.
>
> +config MCTP_TRANSPORT_PCC
> + tristate "MCTP PCC transport"
> + depends on ACPI
Can MCTP_TRANSPORT_PCC be selected when CONFIG_PCC is disabled?
The Kconfig depends only on ACPI but uses pcc_mbox_request_channel() and
pcc_mbox_free_channel() from the PCC mailbox driver (drivers/mailbox/pcc.c).
When CONFIG_PCC is not set, include/acpi/pcc.h provides stub functions
that make pcc_mbox_request_channel() unconditionally return ERR_PTR(-ENODEV).
This means the driver compiles but initialize_MTU() fails, ndo_open() fails,
and no MCTP-over-PCC communication is possible.
> + help
> + Provides a driver to access MCTP devices over PCC transport,
> + A MCTP protocol network device is created via ACPI for each
> + entry in the DSDT/SSDT that matches the identifier. The Platform
> + communication channels are selected from the corresponding
> + entries in the PCCT.
> +
> + Say y here if you need to connect to MCTP endpoints over PCC. To
> + compile as a module, use m; the module will be called mctp-pcc.
[ ... ]
> diff --git a/drivers/net/mctp/mctp-pcc.c b/drivers/net/mctp/mctp-pcc.c
> new file mode 100644
> index 000000000000..fe08fd041d9c
> --- /dev/null
> +++ b/drivers/net/mctp/mctp-pcc.c
[ ... ]
> +static void mctp_pcc_client_rx_callback(struct mbox_client *cl, void *mssg)
> +{
> + struct acpi_pcct_ext_pcc_shared_memory pcc_header;
> + struct mctp_pcc_ndev *mctp_pcc_ndev;
> + struct mctp_pcc_mailbox *inbox;
> + struct mctp_skb_cb *cb;
> + struct sk_buff *skb;
> + int size;
> +
> + mctp_pcc_ndev = container_of(cl, struct mctp_pcc_ndev, inbox.client);
> + inbox = &mctp_pcc_ndev->inbox;
> + memcpy_fromio(&pcc_header, inbox->chan->shmem, sizeof(pcc_header));
> +
> + if (pcc_header.length <= 0) {
> + dev_dstats_rx_dropped(mctp_pcc_ndev->ndev);
> + return;
> + }
> +
> + size = pcc_header.length - sizeof(pcc_header.command) + sizeof(pcc_header);
> + if (memcmp(&pcc_header.command, MCTP_SIGNATURE, MCTP_SIGNATURE_LENGTH) != 0) {
> + dev_dstats_rx_dropped(mctp_pcc_ndev->ndev);
> + return;
> + }
> +
> + skb = netdev_alloc_skb(mctp_pcc_ndev->ndev, size);
> + if (!skb) {
> + dev_dstats_rx_dropped(mctp_pcc_ndev->ndev);
> + return;
> + }
> + skb_put(skb, size);
> + skb->protocol = htons(ETH_P_MCTP);
> + memcpy_fromio(skb->data, inbox->chan->shmem, size);
Can pcc_header.length exceed inbox->chan->shmem_size?
The pcc_header is read from shared memory controlled by the remote endpoint.
The only validation is pcc_header.length <= 0. The size is calculated as:
size = pcc_header.length - sizeof(pcc_header.command) + sizeof(pcc_header)
= pcc_header.length + 12
If the remote endpoint sets pcc_header.length to a value larger than
shmem_size, memcpy_fromio() reads beyond the ioremapped region.
> + dev_dstats_rx_add(mctp_pcc_ndev->ndev, size);
> + skb_pull(skb, sizeof(pcc_header));
> + skb_reset_mac_header(skb);
> + skb_reset_network_header(skb);
> + cb = __mctp_cb(skb);
> + cb->halen = 0;
> + netif_rx(skb);
> +}
[ ... ]
> +static int mctp_pcc_ndo_stop(struct net_device *ndev)
> +{
> + struct mctp_pcc_ndev *mctp_pcc_ndev = netdev_priv(ndev);
> +
> + pcc_mbox_free_channel(mctp_pcc_ndev->outbox.chan);
> + pcc_mbox_free_channel(mctp_pcc_ndev->inbox.chan);
> + return 0;
> +}
Does mctp_pcc_ndo_stop() leak SKBs queued in the mailbox?
Looking at mbox_free_channel() in drivers/mailbox/mailbox.c, the
documentation states "The queued TX requests are simply aborted, no
callbacks are made." The implementation sets chan->cl = NULL and
chan->active_req = NULL but does not free the SKBs stored in
chan->msg_data[].
The mailbox ring buffer can hold up to MBOX_TX_QUEUE_LEN (20) entries.
When the network interface is stopped, any SKBs queued there are leaked
because:
1. The networking stack already returned NETDEV_TX_OK, so it won't free them
2. tx_done will never be called since chan->cl is NULL
The commit message claims "Stopping the interface also frees any packets
that are cached in the mailbox ringbuffer" but this doesn't appear to
happen.
[ ... ]
> +static int initialize_MTU(struct net_device *ndev)
> +{
> + struct mctp_pcc_ndev *mctp_pcc_ndev;
> + struct mctp_pcc_mailbox *outbox;
> + struct pcc_mbox_chan *pchan;
> + int mctp_pcc_mtu;
> +
> + mctp_pcc_mtu = MCTP_MIN_MTU;
> + mctp_pcc_ndev = netdev_priv(ndev);
> + outbox = &mctp_pcc_ndev->outbox;
> + pchan = pcc_mbox_request_channel(&outbox->client, outbox->index);
> + if (IS_ERR(pchan))
> + return -1;
> +
> + mctp_pcc_mtu = pchan->shmem_size;
> + pcc_mbox_free_channel(pchan);
> +
> + mctp_pcc_mtu = mctp_pcc_mtu - sizeof(struct acpi_pcct_ext_pcc_shared_memory);
What happens if pchan->shmem_size is smaller than 16 bytes?
The function subtracts sizeof(struct acpi_pcct_ext_pcc_shared_memory)
(16 bytes) from pchan->shmem_size (u64) through the local int variable
mctp_pcc_mtu. If shmem_size is smaller than 16, the subtraction produces
a negative int which wraps when assigned to ndev->max_mtu (unsigned int),
resulting in a value near UINT_MAX.
When packets are transmitted, mctp_pcc_tx_prepare() calls:
memcpy_toio(outbox->chan->shmem, skb->data, skb->len)
where skb->len can far exceed the actual mapped region (only shmem_size
bytes were ioremapped), causing writes beyond the mapped region.
> + ndev->mtu = MCTP_MIN_MTU;
> + ndev->max_mtu = mctp_pcc_mtu;
> + ndev->min_mtu = MCTP_MIN_MTU;
> +
> + return 0;
> +}
[ ... ]
--
pw-bot: cr
^ permalink raw reply
* Re: [PATCH net-next] net: dsa: qca8k: Use the right GPIO header
From: patchwork-bot+netdevbpf @ 2026-03-29 20:40 UTC (permalink / raw)
To: Linus Walleij; +Cc: andrew, olteanv, davem, edumazet, kuba, pabeni, netdev
In-Reply-To: <20260327-net-dsa-qca8k-v1-1-94e613a5c369@kernel.org>
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Fri, 27 Mar 2026 13:23:45 +0100 you wrote:
> The driver header for qca8k includes the legacy GPIO header
> <linux/gpio.h> but does not use any symbols from it and actually
> wants <linux/gpio/consumer.h> so fix this up.
>
> Signed-off-by: Linus Walleij <linusw@kernel.org>
> ---
> drivers/net/dsa/qca/qca8k.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> [...]
Here is the summary with links:
- [net-next] net: dsa: qca8k: Use the right GPIO header
https://git.kernel.org/netdev/net-next/c/d4383c7c7863
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next v2 13/13] net: renesas: rswitch: add vlan aware switching
From: kernel test robot @ 2026-03-29 20:36 UTC (permalink / raw)
To: Michael Dege, Yoshihiro Shimoda, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: oe-kbuild-all, netdev, linux-renesas-soc, linux-kernel,
Michael Dege
In-Reply-To: <20260327-rswitch_add_vlans-v2-13-d7f4358ca57a@renesas.com>
Hi Michael,
kernel test robot noticed the following build errors:
[auto build test ERROR on 1f318b96cc84d7c2ab792fcc0bfd42a7ca890681]
url: https://github.com/intel-lab-lkp/linux/commits/Michael-Dege/net-renesas-rswitch-improve-port-change-mode-functions/20260329-154812
base: 1f318b96cc84d7c2ab792fcc0bfd42a7ca890681
patch link: https://lore.kernel.org/r/20260327-rswitch_add_vlans-v2-13-d7f4358ca57a%40renesas.com
patch subject: [PATCH net-next v2 13/13] net: renesas: rswitch: add vlan aware switching
config: arm64-defconfig (https://download.01.org/0day-ci/archive/20260330/202603300436.ryIgiB0z-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260330/202603300436.ryIgiB0z-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603300436.ryIgiB0z-lkp@intel.com/
All errors (new ones prefixed by >>):
aarch64-linux-ld: Unexpected GOT/PLT entries detected!
aarch64-linux-ld: Unexpected run-time procedure linkages detected!
aarch64-linux-ld: drivers/net/ethernet/renesas/rswitch_l2.o: in function `rswitch_port_obj_do_add_gwca':
>> drivers/net/ethernet/renesas/rswitch_l2.c:443:(.text+0x11e0): undefined reference to `br_vlan_enabled'
aarch64-linux-ld: drivers/net/ethernet/renesas/rswitch_l2.o: in function `rswitch_port_obj_do_add':
drivers/net/ethernet/renesas/rswitch_l2.c:412:(.text+0x135c): undefined reference to `br_vlan_enabled'
>> aarch64-linux-ld: drivers/net/ethernet/renesas/rswitch_l2.c:423:(.text+0x13bc): undefined reference to `br_vlan_enabled'
vim +443 drivers/net/ethernet/renesas/rswitch_l2.c
402
403 static int rswitch_port_obj_do_add(struct net_device *ndev,
404 struct switchdev_obj_port_vlan *p_vlan)
405 {
406 struct rswitch_device *rdev = netdev_priv(ndev);
407 struct rswitch_private *priv = rdev->priv;
408 struct rswitch_etha *etha = rdev->etha;
409 int err;
410
411 /* Set Rswitch VLAN mode */
412 iowrite32(br_vlan_enabled(rdev->brdev) ? FIELD_PREP(FWGC_SVM, C_TAG) : 0,
413 priv->addr + FWGC);
414
415 err = rswitch_write_vlan_table(priv, p_vlan->vid, etha->index);
416 if (err < 0)
417 return err;
418
419 /* If the default vlan for this port has been set, don't overwrite it. */
420 if (ioread32(etha->addr + EAVCC))
421 return NOTIFY_DONE;
422
> 423 if (br_vlan_enabled(rdev->brdev))
424 rswitch_modify(priv->addr, FWPC0(etha->index), 0, FWPC0_VLANSA | FWPC0_VLANRU);
425
426 rswitch_modify(priv->addr, FWPC2(AGENT_INDEX_GWCA),
427 FIELD_PREP(FWPC2_LTWFW, BIT(etha->index)),
428 0);
429
430 return rswitch_port_set_vlan_tag(etha, p_vlan, false);
431 }
432
433 static int rswitch_port_obj_do_add_gwca(struct net_device *ndev,
434 struct rswitch_private *priv,
435 struct switchdev_obj_port_vlan *p_vlan)
436 {
437 int err;
438
439 if (!(p_vlan->flags & BRIDGE_VLAN_INFO_BRENTRY))
440 return NOTIFY_DONE;
441
442 /* Set Rswitch VLAN mode */
> 443 iowrite32(br_vlan_enabled(ndev) ? FIELD_PREP(FWGC_SVM, C_TAG) : 0, priv->addr + FWGC);
444
445 err = rswitch_write_vlan_table(priv, p_vlan->vid, AGENT_INDEX_GWCA);
446 if (err < 0)
447 return err;
448
449 /* If the default vlan for this port has been set, don't overwrite it. */
450 if (ioread32(priv->addr + GWVCC))
451 return NOTIFY_DONE;
452
453 return rswitch_gwca_set_vlan_tag(priv, p_vlan, false);
454 }
455
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH net 2/2] net/smc: fix potential UAF in smc_pnet_add_ib for smcd device
From: Jakub Kicinski @ 2026-03-29 20:35 UTC (permalink / raw)
To: lixiasong1
Cc: Jakub Kicinski, alibuda, dust.li, sidraya, wenjia, mjambigi,
tonylu, guwen, davem, edumazet, pabeni, horms, linux-rdma,
linux-s390, netdev, linux-kernel, yuehaibing, zhangchangzhong,
weiyongjun1
In-Reply-To: <20260325110352.3833570-3-lixiasong1@huawei.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
net/smc: fix potential UAF in smc_pnet_add_ib for smcd device
This commit fixes a potential use-after-free when accessing an smcd device
in smc_pnet_add_ib(). It resolves the issue by combining the lookup and
apply operations into a single function that holds the smcd_dev_list.mutex
for the duration of both operations.
> diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c
> index 91c0b1c473b2..a1603740167b 100644
> --- a/net/smc/smc_pnet.c
> +++ b/net/smc/smc_pnet.c
[ ... ]
> @@ -351,23 +357,39 @@ static bool smc_pnet_find_ib_apply(char *ib_name, u8 ib_port, char *pnet_name)
> }
>
> /* Find an smcd device by a given name. The device might not exist. */
> -static struct smcd_dev *smc_pnet_find_smcd(char *smcd_name)
> +static struct smcd_dev *__smc_pnet_find_smcd(char *smcd_name)
> {
> struct smcd_dev *smcd_dev;
>
> - mutex_lock(&smcd_dev_list.mutex);
> list_for_each_entry(smcd_dev, &smcd_dev_list.list, list) {
> if (!strncmp(dev_name(&smcd_dev->dibs->dev), smcd_name,
> IB_DEVICE_NAME_MAX - 1) ||
> (smcd_dev->dibs->dev.parent &&
> !strncmp(dev_name(smcd_dev->dibs->dev.parent), smcd_name,
> IB_DEVICE_NAME_MAX - 1)))
> - goto out;
> + return smcd_dev;
> + }
> + return NULL;
> +}
> +
> +/* Find an smcd device by name and apply pnetid under lock. */
> +static bool smc_pnet_find_smcd_apply(char *smcd_name, char *pnet_name)
> +{
> + struct smcd_dev *smcd_dev;
> + bool rc = true;
> +
> + mutex_lock(&smcd_dev_list.mutex);
> + smcd_dev = __smc_pnet_find_smcd(smcd_name);
> + if (smcd_dev) {
> + if (!__smc_pnet_apply_smcd(smcd_dev, pnet_name))
While this prevents the use-after-free in smc_pnet_add_ib() by expanding the
mutex coverage, does the same vulnerability pattern still exist in the
connection handshake paths?
Neither struct smcd_dev nor struct smc_ib_device appear to use reference
counting. During a connection handshake, functions like
smc_pnet_find_ism_resource() and _smc_pnet_find_roce_by_pnetid() find a
device under the mutex, store the raw pointer (e.g., into ini->ism_dev[0]),
and immediately release the mutex.
If a concurrent hot-unplug event triggers smcd_unregister_dev() or
smc_ib_remove_dev() while the handshake process is accessing the device
without holding a lock or reference, could it lead to another use-after-free?
Would a more complete fix require introducing reference counting for both
device structures to ensure they remain valid while pointed to by the
handshake structures?
> + rc = false;
> + else
> + pr_warn_ratelimited("smc: smcd device %s applied user defined pnetid %.16s\n",
> + dev_name(&smcd_dev->dibs->dev),
> + smcd_dev->pnetid);
> }
> - smcd_dev = NULL;
> -out:
> mutex_unlock(&smcd_dev_list.mutex);
> - return smcd_dev;
> + return rc;
> }
^ permalink raw reply
* Re: [PATCH net 1/2] net/smc: fix potential UAF in smc_pnet_add_ib for ib device
From: Jakub Kicinski @ 2026-03-29 20:35 UTC (permalink / raw)
To: lixiasong1
Cc: Jakub Kicinski, alibuda, dust.li, sidraya, wenjia, mjambigi,
tonylu, guwen, davem, edumazet, pabeni, horms, linux-rdma,
linux-s390, netdev, linux-kernel, yuehaibing, zhangchangzhong,
weiyongjun1
In-Reply-To: <20260325110352.3833570-2-lixiasong1@huawei.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
No issues found.
--
pw-bot: cr
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox