]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
dpaa2-eth: fix xdp_rxq_info leak
authorFushuai Wang <wangfushuai@baidu.com>
Mon, 7 Jul 2025 20:06:22 +0000 (16:06 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Jul 2025 13:57:49 +0000 (15:57 +0200)
[ Upstream commit 2def09ead4ad5907988b655d1e1454003aaf8297 ]

The driver registered xdp_rxq_info structures via xdp_rxq_info_reg()
but failed to properly unregister them in error paths and during
removal.

Fixes: d678be1dc1ec ("dpaa2-eth: add XDP_REDIRECT support")
Signed-off-by: Fushuai Wang <wangfushuai@baidu.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Link: https://patch.msgid.link/20250626133003.80136-1-wangfushuai@baidu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c

index acbb26cb2177e624593a2c3000f0e659361595e8..07d8c9e41328e9ed101e15365d04b46a68b59ae0 100644 (file)
@@ -3512,6 +3512,7 @@ static int dpaa2_eth_setup_rx_flow(struct dpaa2_eth_priv *priv,
                                         MEM_TYPE_PAGE_ORDER0, NULL);
        if (err) {
                dev_err(dev, "xdp_rxq_info_reg_mem_model failed\n");
+               xdp_rxq_info_unreg(&fq->channel->xdp_rxq);
                return err;
        }
 
@@ -4004,17 +4005,25 @@ static int dpaa2_eth_bind_dpni(struct dpaa2_eth_priv *priv)
                        return -EINVAL;
                }
                if (err)
-                       return err;
+                       goto out;
        }
 
        err = dpni_get_qdid(priv->mc_io, 0, priv->mc_token,
                            DPNI_QUEUE_TX, &priv->tx_qdid);
        if (err) {
                dev_err(dev, "dpni_get_qdid() failed\n");
-               return err;
+               goto out;
        }
 
        return 0;
+
+out:
+       while (i--) {
+               if (priv->fq[i].type == DPAA2_RX_FQ &&
+                   xdp_rxq_info_is_reg(&priv->fq[i].channel->xdp_rxq))
+                       xdp_rxq_info_unreg(&priv->fq[i].channel->xdp_rxq);
+       }
+       return err;
 }
 
 /* Allocate rings for storing incoming frame descriptors */
@@ -4371,6 +4380,17 @@ static void dpaa2_eth_del_ch_napi(struct dpaa2_eth_priv *priv)
        }
 }
 
+static void dpaa2_eth_free_rx_xdp_rxq(struct dpaa2_eth_priv *priv)
+{
+       int i;
+
+       for (i = 0; i < priv->num_fqs; i++) {
+               if (priv->fq[i].type == DPAA2_RX_FQ &&
+                   xdp_rxq_info_is_reg(&priv->fq[i].channel->xdp_rxq))
+                       xdp_rxq_info_unreg(&priv->fq[i].channel->xdp_rxq);
+       }
+}
+
 static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
 {
        struct device *dev;
@@ -4559,6 +4579,7 @@ err_alloc_percpu_extras:
        free_percpu(priv->percpu_stats);
 err_alloc_percpu_stats:
        dpaa2_eth_del_ch_napi(priv);
+       dpaa2_eth_free_rx_xdp_rxq(priv);
 err_bind:
        dpaa2_eth_free_dpbp(priv);
 err_dpbp_setup:
@@ -4610,6 +4631,7 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
        free_percpu(priv->percpu_extras);
 
        dpaa2_eth_del_ch_napi(priv);
+       dpaa2_eth_free_rx_xdp_rxq(priv);
        dpaa2_eth_free_dpbp(priv);
        dpaa2_eth_free_dpio(priv);
        dpaa2_eth_free_dpni(priv);