netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Simon Horman <horms@kernel.org>
To: Parvathi Pudi <parvathi@couthit.com>
Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, danishanwar@ti.com,
	rogerq@kernel.org, pmohan@couthit.com, basharath@couthit.com,
	afd@ti.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, alok.a.tiwari@oracle.com,
	pratheesh@ti.com, j-rameshbabu@ti.com, vigneshr@ti.com,
	praneeth@ti.com, srk@ti.com, rogerq@ti.com, krishna@couthit.com,
	mohan@couthit.com
Subject: Re: [PATCH net-next v5 1/3] net: ti: icssm-prueth: Adds helper functions to configure and maintain FDB
Date: Mon, 17 Nov 2025 21:07:19 +0000	[thread overview]
Message-ID: <aRuOh-O99Xwo1nG0@horms.kernel.org> (raw)
In-Reply-To: <20251113101229.675141-2-parvathi@couthit.com>

On Thu, Nov 13, 2025 at 03:40:21PM +0530, Parvathi Pudi wrote:

...

> +static u16 icssm_prueth_sw_fdb_find_open_slot(struct fdb_tbl *fdb_tbl)
> +{
> +	u8 flags;
> +	u16 i;
> +
> +	for (i = 0; i < FDB_MAC_TBL_MAX_ENTRIES; i++) {
> +		flags = readb(&fdb_tbl->mac_tbl_a->mac_tbl_entry[i].flags);
> +		if (!(flags & FLAG_ACTIVE))
> +			break;

Hi Parvathi, all,

If the condition above is never met....

> +	}
> +
> +	return i;

Then FDB_MAC_TBL_MAX_ENTRIES will be returned here.
Which is written to bkt_info->bucket_idx by
icssm_prueth_sw_insert_fdb_entry()...

> +}
> +
> +static int
> +icssm_prueth_sw_find_fdb_insert(struct fdb_tbl *fdb, struct prueth *prueth,
> +				struct fdb_index_tbl_entry __iomem *bkt_info,
> +				const u8 *mac, const u8 port)
> +{
> +	struct fdb_mac_tbl_array __iomem *mac_tbl = fdb->mac_tbl_a;
> +	struct fdb_mac_tbl_entry __iomem *e;
> +	u8 mac_from_hw[ETH_ALEN];
> +	u16 bucket_entries;
> +	u16 mac_tbl_idx;
> +	int i, ret;
> +	s8 cmp;
> +
> +	mac_tbl_idx = readw(&bkt_info->bucket_idx);

That value will be read here...

> +	bucket_entries = readw(&bkt_info->bucket_entries);
> +
> +	for (i = 0; i < bucket_entries; i++, mac_tbl_idx++) {
> +		e = &mac_tbl->mac_tbl_entry[mac_tbl_idx];

And used here, without any bounds checking.

But if mac_tbl_idx is FDB_MAC_TBL_MAX_ENTRIES then
the access to mac_tble_entry will overflow, as
it only has FDB_MAC_TBL_MAX_ENTRIES elements.

This, and most of my review points for this patch set were
flagged by Claude Code with https://github.com/masoncl/review-prompts/

...

> +static int icssm_prueth_sw_insert_fdb_entry(struct prueth_emac *emac,
> +					    const u8 *mac, u8 is_static)
> +{
> +	struct fdb_index_tbl_entry __iomem *bucket_info;
> +	struct fdb_mac_tbl_entry __iomem *mac_info;
> +	struct prueth *prueth = emac->prueth;
> +	struct prueth_emac *other_emac;
> +	enum prueth_port other_port_id;
> +	u8 hash_val, mac_tbl_idx;
> +	struct fdb_tbl *fdb;
> +	u8 flags;
> +	u16 val;
> +	s16 ret;
> +	int err;
> +
> +	fdb = prueth->fdb_tbl;
> +	other_port_id = (emac->port_id == PRUETH_PORT_MII0) ?
> +			 PRUETH_PORT_MII1 : PRUETH_PORT_MII0;
> +
> +	other_emac = prueth->emac[other_port_id - 1];
> +
> +	if (fdb->total_entries == FDB_MAC_TBL_MAX_ENTRIES)
> +		return -ENOMEM;

Access to total_entries outside of icssm_prueth_sw_fdb_spin_lock.
Seems racy here. Likewise for the similar check in
icssm_prueth_sw_delete_fdb_entry().

Flagged by Claude Code with https://github.com/masoncl/review-prompts/

> +
> +	if (ether_addr_equal(mac, emac->mac_addr) ||
> +	    ether_addr_equal(mac, other_emac->mac_addr)) {
> +		/* Don't insert fdb of own mac addr */
> +		return -EINVAL;
> +	}
> +
> +	/* Get the bucket that the mac belongs to */
> +	hash_val = icssm_prueth_sw_fdb_hash(mac);
> +	bucket_info = FDB_IDX_TBL_ENTRY(hash_val);
> +
> +	if (!readw(&bucket_info->bucket_entries)) {
> +		mac_tbl_idx = icssm_prueth_sw_fdb_find_open_slot(fdb);
> +		writew(mac_tbl_idx, &bucket_info->bucket_idx);
> +	}
> +
> +	ret = icssm_prueth_sw_find_fdb_insert(fdb, prueth, bucket_info, mac,
> +					      emac->port_id - 1);
> +	if (ret < 0)
> +		/* mac is already in fdb table */
> +		return 0;
> +
> +	mac_tbl_idx = ret;
> +
> +	err = icssm_prueth_sw_fdb_spin_lock(fdb);
> +	if (err) {
> +		dev_err(prueth->dev, "PRU lock timeout %d\n", ret);
> +		return err;
> +	}
> +
> +	mac_info = icssm_prueth_sw_find_free_mac(prueth, bucket_info,
> +						 mac_tbl_idx, NULL,
> +						 mac);
> +	if (!mac_info) {
> +		/* Should not happen */
> +		dev_warn(prueth->dev, "OUT of FDB MEM\n");

This appears to leak icssm_prueth_sw_fdb_spin_lock.

Also flagged by Claude Code with https://github.com/masoncl/review-prompts/

> +		return -ENOMEM;
> +	}
> +
> +	memcpy_toio(mac_info->mac, mac, ETH_ALEN);
> +	writew(0, &mac_info->age);
> +	writeb(emac->port_id - 1, &mac_info->port);
> +
> +	flags = readb(&mac_info->flags);
> +	if (is_static)
> +		flags |= FLAG_IS_STATIC;
> +	else
> +		flags &= ~FLAG_IS_STATIC;
> +
> +	/* bit 1 - active */
> +	flags |= FLAG_ACTIVE;
> +	writeb(flags, &mac_info->flags);
> +
> +	val = readw(&bucket_info->bucket_entries);
> +	val++;
> +	writew(val, &bucket_info->bucket_entries);
> +
> +	fdb->total_entries++;
> +
> +	icssm_prueth_sw_fdb_spin_unlock(fdb);
> +
> +	dev_dbg(prueth->dev, "added fdb: %pM port=%d total_entries=%u\n",
> +		mac, emac->port_id, fdb->total_entries);

Less important, but I think the value of total_entries could
be out of date as it's accessed outside of the lock.
Perhaps it would be good to stash the value into a local variable while
the lock is still held?

Likewise in icssm_prueth_sw_delete_fdb_entry().

> +
> +	return 0;
> +}
> +
> +static int icssm_prueth_sw_delete_fdb_entry(struct prueth_emac *emac,
> +					    const u8 *mac, u8 is_static)
> +{
> +	struct fdb_index_tbl_entry __iomem *bucket_info;
> +	struct fdb_mac_tbl_entry __iomem *mac_info;
> +	struct fdb_mac_tbl_array __iomem *mt;
> +	u8 hash_val, mac_tbl_idx;
> +	u16 idx, entries, val;
> +	struct prueth *prueth;
> +	s16 ret, left, right;
> +	struct fdb_tbl *fdb;
> +	u8 flags;
> +	int err;
> +
> +	prueth = emac->prueth;
> +	fdb = prueth->fdb_tbl;
> +	mt = fdb->mac_tbl_a;
> +
> +	if (fdb->total_entries == 0)
> +		return 0;
> +
> +	/* Get the bucket that the mac belongs to */
> +	hash_val = icssm_prueth_sw_fdb_hash(mac);
> +	bucket_info = FDB_IDX_TBL_ENTRY(hash_val);
> +
> +	ret = icssm_prueth_sw_fdb_search(mt, bucket_info, mac);
> +	if (ret < 0)
> +		return ret;
> +
> +	mac_tbl_idx = ret;
> +	mac_info = FDB_MAC_TBL_ENTRY(mac_tbl_idx);
> +
> +	err = icssm_prueth_sw_fdb_spin_lock(fdb);
> +	if (err) {
> +		dev_err(prueth->dev, "PRU lock timeout %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* Shift all elements in bucket to the left. No need to
> +	 * update index table since only shifting within bucket.
> +	 */
> +	left = mac_tbl_idx;
> +	idx = readw(&bucket_info->bucket_idx);
> +	entries = readw(&bucket_info->bucket_entries);
> +	right = idx + entries - 1;
> +	icssm_prueth_sw_fdb_move_range_left(prueth, left, right);
> +
> +	/* Remove end of bucket from table */
> +	mac_info = FDB_MAC_TBL_ENTRY(right);
> +	flags = readb(&mac_info->flags);
> +	/* active = 0 */
> +	flags &= ~FLAG_ACTIVE;
> +	writeb(flags, &mac_info->flags);
> +	val = readw(&bucket_info->bucket_entries);
> +	val--;
> +	writew(val, &bucket_info->bucket_entries);
> +	fdb->total_entries--;
> +
> +	icssm_prueth_sw_fdb_spin_unlock(fdb);
> +
> +	dev_dbg(prueth->dev, "del fdb: %pM total_entries=%u\n",
> +		mac, fdb->total_entries);
> +
> +	return 0;
> +}

...

  reply	other threads:[~2025-11-17 21:07 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-13 10:10 [PATCH net-next v5 0/3] STP/RSTP SWITCH support for PRU-ICSSM Ethernet driver Parvathi Pudi
2025-11-13 10:10 ` [PATCH net-next v5 1/3] net: ti: icssm-prueth: Adds helper functions to configure and maintain FDB Parvathi Pudi
2025-11-17 21:07   ` Simon Horman [this message]
2025-11-20  6:20     ` Parvathi Pudi
2025-11-13 10:10 ` [PATCH net-next v5 2/3] net: ti: icssm-prueth: Adds switchdev support for icssm_prueth driver Parvathi Pudi
2025-11-17 21:08   ` Simon Horman
2025-11-20  6:22     ` Parvathi Pudi
2025-11-13 10:10 ` [PATCH net-next v5 3/3] net: ti: icssm-prueth: Adds support for ICSSM RSTP switch Parvathi Pudi
2025-11-17 21:09   ` Simon Horman
2025-11-20  6:25     ` Parvathi Pudi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aRuOh-O99Xwo1nG0@horms.kernel.org \
    --to=horms@kernel.org \
    --cc=afd@ti.com \
    --cc=alok.a.tiwari@oracle.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=basharath@couthit.com \
    --cc=danishanwar@ti.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=j-rameshbabu@ti.com \
    --cc=krishna@couthit.com \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mohan@couthit.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=parvathi@couthit.com \
    --cc=pmohan@couthit.com \
    --cc=praneeth@ti.com \
    --cc=pratheesh@ti.com \
    --cc=rogerq@kernel.org \
    --cc=rogerq@ti.com \
    --cc=srk@ti.com \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).