Commit 3e389310 authored by Jenishkumar Maheshbhai Patel's avatar Jenishkumar Maheshbhai Patel Committed by Wang Hai
Browse files

net: mvpp2: clear BM pool before initialization

stable inclusion
from stable-v5.10.210
commit 83f99138bf3b396f761600ab488054396fb5768f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9Q9DC
CVE: CVE-2024-35837

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=83f99138bf3b396f761600ab488054396fb5768f



--------------------------------

[ Upstream commit 9f538b415db862e74b8c5d3abbccfc1b2b6caa38 ]

Register value persist after booting the kernel using
kexec which results in kernel panic. Thus clear the
BM pool registers before initialisation to fix the issue.

Fixes: 3f518509 ("ethernet: Add new driver for Marvell Armada 375 network unit")
Signed-off-by: default avatarJenishkumar Maheshbhai Patel <jpatel2@marvell.com>
Reviewed-by: default avatarMaxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://lore.kernel.org/r/20240119035914.2595665-1-jpatel2@marvell.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarWang Hai <wanghai38@huawei.com>
parent cdbb8c63
Loading
Loading
Loading
Loading
+26 −1
Original line number Diff line number Diff line
@@ -581,12 +581,38 @@ static int mvpp2_bm_pools_init(struct device *dev, struct mvpp2 *priv)
	return err;
}

/* Cleanup pool before actual initialization in the OS */
static void mvpp2_bm_pool_cleanup(struct mvpp2 *priv, int pool_id)
{
	unsigned int thread = mvpp2_cpu_to_thread(priv, get_cpu());
	u32 val;
	int i;

	/* Drain the BM from all possible residues left by firmware */
	for (i = 0; i < MVPP2_BM_POOL_SIZE_MAX; i++)
		mvpp2_thread_read(priv, thread, MVPP2_BM_PHY_ALLOC_REG(pool_id));

	put_cpu();

	/* Stop the BM pool */
	val = mvpp2_read(priv, MVPP2_BM_POOL_CTRL_REG(pool_id));
	val |= MVPP2_BM_STOP_MASK;
	mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(pool_id), val);
}

static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv)
{
	enum dma_data_direction dma_dir = DMA_FROM_DEVICE;
	int i, err, poolnum = MVPP2_BM_POOLS_NUM;
	struct mvpp2_port *port;

	if (priv->percpu_pools)
		poolnum = mvpp2_get_nrxqs(priv) * 2;

	/* Clean up the pool state in case it contains stale state */
	for (i = 0; i < poolnum; i++)
		mvpp2_bm_pool_cleanup(priv, i);

	if (priv->percpu_pools) {
		for (i = 0; i < priv->port_count; i++) {
			port = priv->port_list[i];
@@ -596,7 +622,6 @@ static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv)
			}
		}

		poolnum = mvpp2_get_nrxqs(priv) * 2;
		for (i = 0; i < poolnum; i++) {
			/* the pool in use */
			int pn = i / (poolnum / 2);