Commit 2def09ea authored by Fushuai Wang's avatar Fushuai Wang Committed by Jakub Kicinski
Browse files

dpaa2-eth: fix xdp_rxq_info leak



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: d678be1d ("dpaa2-eth: add XDP_REDIRECT support")
Signed-off-by: default avatarFushuai Wang <wangfushuai@baidu.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Reviewed-by: default avatarIoana Ciornei <ioana.ciornei@nxp.com>
Link: https://patch.msgid.link/20250626133003.80136-1-wangfushuai@baidu.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent d72411d2
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -3939,6 +3939,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;
	}

@@ -4432,17 +4433,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 */
@@ -4825,6 +4834,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;
@@ -5028,6 +5048,7 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
	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_dpbps(priv);
err_dpbp_setup:
@@ -5080,6 +5101,7 @@ static void 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_dpbps(priv);
	dpaa2_eth_free_dpio(priv);
	dpaa2_eth_free_dpni(priv);